diff --git a/wp-content/plugins/buddypress/bp-activity/admin/css/admin.css b/wp-content/plugins/buddypress/bp-activity/admin/css/admin.css
index bf770824eeff1dc5f7ee44b6eff46e53c15e723d..b2a69a7f4ad27ab15d835637c58bbb5072737688 100644
--- a/wp-content/plugins/buddypress/bp-activity/admin/css/admin.css
+++ b/wp-content/plugins/buddypress/bp-activity/admin/css/admin.css
@@ -74,4 +74,7 @@
 }
 #bp-activities-primaryid {
 	margin-bottom: 1em;
+}
+.column-action {
+	width: 12%;
 }
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-activity/admin/css/admin.min.css b/wp-content/plugins/buddypress/bp-activity/admin/css/admin.min.css
index 8b5ac3dc2606713df4aafdd2316b6300cfce3fa4..d10ded4777e687901928df2a1e02996f42d73ce7 100644
--- a/wp-content/plugins/buddypress/bp-activity/admin/css/admin.min.css
+++ b/wp-content/plugins/buddypress/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
diff --git a/wp-content/plugins/buddypress/bp-activity/admin/js/admin.js b/wp-content/plugins/buddypress/bp-activity/admin/js/admin.js
index 4f4d4794cdb3e8d66b904429b9f329305da55e17..95654c59852925cd35b680cd4789d0b22acd9886 100644
--- a/wp-content/plugins/buddypress/bp-activity/admin/js/admin.js
+++ b/wp-content/plugins/buddypress/bp-activity/admin/js/admin.js
@@ -162,6 +162,11 @@ $(document).ready( function () {
 
 	// On the edit screen, unload the close/open toggle js for the action & content metaboxes
 	$( '#bp_activity_action h3, #bp_activity_content h3' ).unbind( 'click' );
+
+	// redo the post box toggles to reset the one made by comment.js in favor
+	// of activity administration page id so that metaboxes are still collapsible 
+	// in single Activity Administration screen.
+	postboxes.add_postbox_toggles( bp_activity_admin_vars.page );
 });
 
 })(jQuery);
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-activity/admin/js/admin.min.js b/wp-content/plugins/buddypress/bp-activity/admin/js/admin.min.js
index 53c59ef39adf411fe34a9ec8646974d73fe78c98..fc4e8ce89d2805c96572d14196f17dc9913efd61 100644
--- a/wp-content/plugins/buddypress/bp-activity/admin/js/admin.min.js
+++ b/wp-content/plugins/buddypress/bp-activity/admin/js/admin.min.js
@@ -1 +1 @@
-(function(b){var a={init:function(){b(document).on("click",".row-actions a.reply",a.open);b(document).on("click","#bp-activities-container a.cancel",a.close);b(document).on("click","#bp-activities-container a.save",a.send);b(document).on("keyup","#bp-activities:visible",function(c){if(27==c.which){a.close()}})},open:function(d){var c=b("#bp-activities-container").hide();b(this).parents("tr").after(c);c.fadeIn("300");b("#bp-activities").focus();return false},close:function(c){b("#bp-activities-container").fadeOut("200",function(){b("#bp-activities").val("").blur();b("#bp-replysubmit .error").html("").hide();b("#bp-replysubmit .waiting").hide()});return false},send:function(d){b("#bp-replysubmit .error").hide();b("#bp-replysubmit .waiting").show();var c={};c["_ajax_nonce-bp-activity-admin-reply"]=b('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val();c.action="bp-activity-admin-reply";c.content=b("#bp-activities").val();c.parent_id=b("#bp-activities-container").prev().data("parent_id");c.root_id=b("#bp-activities-container").prev().data("root_id");b.ajax({data:c,type:"POST",url:ajaxurl,error:function(e){a.error(e)},success:function(e){a.show(e)}});return false},error:function(c){var d=c.statusText;b("#bp-replysubmit .waiting").hide();if(c.responseText){d=c.responseText.replace(/<.[^<>]*?>/g,"")}if(d){b("#bp-replysubmit .error").html(d).show()}},show:function(d){var e,f,c;if(typeof(d)=="string"){a.error({responseText:d});return false}c=wpAjax.parseAjaxResponse(d);if(c.errors){a.error({responseText:wpAjax.broken});return false}c=c.responses[0];b("#bp-activities-container").fadeOut("200",function(){b("#bp-activities").val("").blur();b("#bp-replysubmit .error").html("").hide();b("#bp-replysubmit .waiting").hide();b("#bp-activities-container").before(c.data);f=b("#activity-"+c.id);e=f.closest(".widefat").css("backgroundColor");f.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:e},300)})}};b(document).ready(function(){a.init();b("#bp_activity_action h3, #bp_activity_content h3").unbind("click")})})(jQuery);
\ No newline at end of file
+(function(b){var a={init:function(){b(document).on("click",".row-actions a.reply",a.open);b(document).on("click","#bp-activities-container a.cancel",a.close);b(document).on("click","#bp-activities-container a.save",a.send);b(document).on("keyup","#bp-activities:visible",function(c){if(27==c.which){a.close()}})},open:function(d){var c=b("#bp-activities-container").hide();b(this).parents("tr").after(c);c.fadeIn("300");b("#bp-activities").focus();return false},close:function(c){b("#bp-activities-container").fadeOut("200",function(){b("#bp-activities").val("").blur();b("#bp-replysubmit .error").html("").hide();b("#bp-replysubmit .waiting").hide()});return false},send:function(d){b("#bp-replysubmit .error").hide();b("#bp-replysubmit .waiting").show();var c={};c["_ajax_nonce-bp-activity-admin-reply"]=b('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val();c.action="bp-activity-admin-reply";c.content=b("#bp-activities").val();c.parent_id=b("#bp-activities-container").prev().data("parent_id");c.root_id=b("#bp-activities-container").prev().data("root_id");b.ajax({data:c,type:"POST",url:ajaxurl,error:function(e){a.error(e)},success:function(e){a.show(e)}});return false},error:function(c){var d=c.statusText;b("#bp-replysubmit .waiting").hide();if(c.responseText){d=c.responseText.replace(/<.[^<>]*?>/g,"")}if(d){b("#bp-replysubmit .error").html(d).show()}},show:function(d){var e,f,c;if(typeof(d)=="string"){a.error({responseText:d});return false}c=wpAjax.parseAjaxResponse(d);if(c.errors){a.error({responseText:wpAjax.broken});return false}c=c.responses[0];b("#bp-activities-container").fadeOut("200",function(){b("#bp-activities").val("").blur();b("#bp-replysubmit .error").html("").hide();b("#bp-replysubmit .waiting").hide();b("#bp-activities-container").before(c.data);f=b("#activity-"+c.id);e=f.closest(".widefat").css("backgroundColor");f.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:e},300)})}};b(document).ready(function(){a.init();b("#bp_activity_action h3, #bp_activity_content h3").unbind("click");postboxes.add_postbox_toggles(bp_activity_admin_vars.page)})})(jQuery);
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-actions.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-actions.php
index a266e9597ea6ea19da7ce815c1db49b402a40fc4..f8c5d524adeaf21c7ad8207ec3ee364f7048684d 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-actions.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-actions.php
@@ -13,7 +13,7 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Allow core components and dependent plugins to register activity actions
+ * Allow core components and dependent plugins to register activity actions.
  *
  * @since BuddyPress (1.2)
  *
@@ -25,7 +25,7 @@ function bp_register_activity_actions() {
 add_action( 'bp_init', 'bp_register_activity_actions', 8 );
 
 /**
- * Allow core components and dependent plugins to register activity actions
+ * Catch and route requests for single activity item permalinks.
  *
  * @since BuddyPress (1.2)
  *
@@ -38,11 +38,11 @@ add_action( 'bp_init', 'bp_register_activity_actions', 8 );
  * @uses bp_core_get_user_domain()
  * @uses groups_get_group()
  * @uses bp_get_group_permalink()
- * @uses apply_filters_ref_array() To call the 'bp_activity_permalink_redirect_url' hook
+ * @uses apply_filters_ref_array() To call the 'bp_activity_permalink_redirect_url' hook.
  * @uses bp_core_redirect()
  * @uses bp_get_root_domain()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_permalink_router() {
 
@@ -124,7 +124,7 @@ add_action( 'bp_actions', 'bp_activity_action_permalink_router' );
  * @uses do_action() Calls 'bp_activity_action_delete_activity' hook to allow actions to be taken after the activity is deleted.
  * @uses bp_core_redirect()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_delete_activity( $activity_id = 0 ) {
 
@@ -169,12 +169,13 @@ function bp_activity_action_delete_activity( $activity_id = 0 ) {
 add_action( 'bp_actions', 'bp_activity_action_delete_activity' );
 
 /**
- * Mark specific activity item as spam and redirect to previous page
+ * Mark specific activity item as spam and redirect to previous page.
+ *
+ * @since BuddyPress (1.6)
  *
  * @global object $bp BuddyPress global settings
  * @param int $activity_id Activity id to be deleted. Defaults to 0.
- * @return bool False on failure
- * @since BuddyPress (1.6)
+ * @return bool False on failure.
  */
 function bp_activity_action_spam_activity( $activity_id = 0 ) {
 	global $bp;
@@ -241,7 +242,7 @@ add_action( 'bp_actions', 'bp_activity_action_spam_activity' );
  * @uses bp_core_redirect()
  * @uses apply_filters() To call 'bp_activity_custom_update' hook.
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_post_update() {
 
@@ -253,9 +254,15 @@ function bp_activity_action_post_update() {
 	check_admin_referer( 'post_update', '_wpnonce_post_update' );
 
 	// Get activity info
-	$content = apply_filters( 'bp_activity_post_update_content', $_POST['whats-new']             );
-	$object  = apply_filters( 'bp_activity_post_update_object',  $_POST['whats-new-post-object'] );
-	$item_id = apply_filters( 'bp_activity_post_update_item_id', $_POST['whats-new-post-in']     );
+	$content = apply_filters( 'bp_activity_post_update_content', $_POST['whats-new'] );
+
+	if ( ! empty( $_POST['whats-new-post-object'] ) ) {
+		$object = apply_filters( 'bp_activity_post_update_object', $_POST['whats-new-post-object'] );
+	}
+
+	if ( ! empty( $_POST['whats-new-post-in'] ) ) {
+		$item_id = apply_filters( 'bp_activity_post_update_item_id', $_POST['whats-new-post-in'] );
+	}
 
 	// No activity content so provide feedback and redirect
 	if ( empty( $content ) ) {
@@ -305,7 +312,7 @@ add_action( 'bp_actions', 'bp_activity_action_post_update' );
  * @uses bp_activity_new_comment()
  * @uses wp_get_referer()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_post_comment() {
 
@@ -353,7 +360,7 @@ add_action( 'bp_actions', 'bp_activity_action_post_comment' );
  * @uses bp_core_redirect()
  * @uses wp_get_referer()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_mark_favorite() {
 
@@ -387,7 +394,7 @@ add_action( 'bp_actions', 'bp_activity_action_mark_favorite' );
  * @uses bp_core_redirect()
  * @uses wp_get_referer()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_remove_favorite() {
 
@@ -407,18 +414,17 @@ function bp_activity_action_remove_favorite() {
 add_action( 'bp_actions', 'bp_activity_action_remove_favorite' );
 
 /**
- * Load the sitewide feed.
+ * Load the sitewide activity feed.
  *
  * @since BuddyPress (1.0)
  *
  * @global object $bp BuddyPress global settings
- * @global object $wp_query
  * @uses bp_is_activity_component()
  * @uses bp_is_current_action()
  * @uses bp_is_user()
  * @uses status_header()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_sitewide_feed() {
 	global $bp;
@@ -441,16 +447,15 @@ function bp_activity_action_sitewide_feed() {
 add_action( 'bp_actions', 'bp_activity_action_sitewide_feed' );
 
 /**
- * Load a user's personal feed.
+ * Load a user's personal activity feed.
  *
  * @since BuddyPress (1.0)
  *
- * @global object $wp_query
  * @uses bp_is_user_activity()
  * @uses bp_is_current_action()
  * @uses status_header()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_personal_feed() {
 	if ( ! bp_is_user_activity() || ! bp_is_current_action( 'feed' ) ) {
@@ -472,11 +477,10 @@ function bp_activity_action_personal_feed() {
 add_action( 'bp_actions', 'bp_activity_action_personal_feed' );
 
 /**
- * Load a user's friends feed.
+ * Load a user's friends' activity feed.
  *
  * @since BuddyPress (1.0)
  *
- * @global object $wp_query
  * @uses bp_is_active()
  * @uses bp_is_user_activity()
  * @uses bp_is_current_action()
@@ -484,7 +488,7 @@ add_action( 'bp_actions', 'bp_activity_action_personal_feed' );
  * @uses bp_is_action_variable()
  * @uses status_header()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_friends_feed() {
 	if ( ! bp_is_active( 'friends' ) || ! bp_is_user_activity() || ! bp_is_current_action( bp_get_friends_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) {
@@ -506,11 +510,10 @@ function bp_activity_action_friends_feed() {
 add_action( 'bp_actions', 'bp_activity_action_friends_feed' );
 
 /**
- * Load a user's my groups feed.
+ * Load the activity feed for a user's groups.
  *
  * @since BuddyPress (1.2)
  *
- * @global object $wp_query
  * @uses bp_is_active()
  * @uses bp_is_user_activity()
  * @uses bp_is_current_action()
@@ -518,7 +521,7 @@ add_action( 'bp_actions', 'bp_activity_action_friends_feed' );
  * @uses bp_is_action_variable()
  * @uses status_header()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_my_groups_feed() {
 	if ( ! bp_is_active( 'groups' ) || ! bp_is_user_activity() || ! bp_is_current_action( bp_get_groups_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) {
@@ -552,13 +555,12 @@ add_action( 'bp_actions', 'bp_activity_action_my_groups_feed' );
  *
  * @since BuddyPress (1.2)
  *
- * @global object $wp_query
  * @uses bp_is_user_activity()
  * @uses bp_is_current_action()
  * @uses bp_is_action_variable()
  * @uses status_header()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_mentions_feed() {
 	if ( ! bp_activity_do_mentions() ) {
@@ -590,13 +592,12 @@ add_action( 'bp_actions', 'bp_activity_action_mentions_feed' );
  *
  * @since BuddyPress (1.2)
  *
- * @global object $wp_query
  * @uses bp_is_user_activity()
  * @uses bp_is_current_action()
  * @uses bp_is_action_variable()
  * @uses status_header()
  *
- * @return bool False on failure
+ * @return bool False on failure.
  */
 function bp_activity_action_favorites_feed() {
 	if ( ! bp_is_user_activity() || ! bp_is_current_action( 'favorites' ) || ! bp_is_action_variable( 'feed', 0 ) ) {
@@ -622,10 +623,11 @@ function bp_activity_action_favorites_feed() {
 add_action( 'bp_actions', 'bp_activity_action_favorites_feed' );
 
 /**
- * Loads Akismet
+ * Loads Akismet filtering for activity.
  *
- * @global object $bp BuddyPress global settings
  * @since BuddyPress (1.6)
+ *
+ * @global object $bp BuddyPress global settings
  */
 function bp_activity_setup_akismet() {
 	global $bp;
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-admin.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-admin.php
index a65ddff3c787490be1ef06c53b680f8a1d038e4d..0150595b84bc9154aebd418076569b9f6004fb92 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-admin.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-admin.php
@@ -1,12 +1,12 @@
 <?php
 /**
- * BuddyPress Activity component admin screen
+ * BuddyPress Activity component admin screen.
  *
- * Props to WordPress core for the Comments admin screen, and its contextual help text,
- * on which this implementation is heavily based.
+ * Props to WordPress core for the Comments admin screen, and its contextual
+ * help text, on which this implementation is heavily based.
  *
  * @package BuddyPress
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  * @subpackage Activity
  */
 
@@ -21,20 +21,17 @@ if ( is_admin() && ! empty( $_REQUEST['page'] ) && 'bp-activity' == $_REQUEST['p
 	add_filter( 'set-screen-option', 'bp_activity_admin_screen_options', 10, 3 );
 
 /**
- * Registers the Activity component admin screen
+ * Register the Activity component admin screen.
  *
  * @since BuddyPress (1.6)
  */
 function bp_activity_add_admin_menu() {
 
-	if ( ! bp_current_user_can( 'bp_moderate' ) )
-		return;
-
 	// Add our screen
 	$hook = add_menu_page(
 		__( 'Activity', 'buddypress' ),
 		__( 'Activity', 'buddypress' ),
-		'manage_options',
+		'bp_moderate',
 		'bp-activity',
 		'bp_activity_admin',
 		'div'
@@ -46,12 +43,16 @@ function bp_activity_add_admin_menu() {
 add_action( bp_core_admin_hook(), 'bp_activity_add_admin_menu' );
 
 /**
- * Add activity component to custom menus array
+ * Add activity component to custom menus array.
  *
- * @since BuddyPress (1.7)
+ * Several BuddyPress components have top-level menu items in the Dashboard,
+ * which all appear together in the middle of the Dashboard menu. This function
+ * adds the Activity page to the array of these menu items.
  *
- * @param array $custom_menus
- * @return array
+ * @since BuddyPress (1.7.0)
+ *
+ * @param array $custom_menus The list of top-level BP menu items.
+ * @return array $custom_menus List of top-level BP menu items, with Activity added
  */
 function bp_activity_admin_menu_order( $custom_menus = array() ) {
 	array_push( $custom_menus, 'bp-activity' );
@@ -60,10 +61,12 @@ function bp_activity_admin_menu_order( $custom_menus = array() ) {
 add_filter( 'bp_admin_menu_order', 'bp_activity_admin_menu_order' );
 
 /**
- * AJAX receiver for Activity replies via the admin screen. Adds a new activity
- * comment, and returns HTML for a new table row.
+ * AJAX receiver for Activity replies via the admin screen.
  *
- * @since BuddyPress (1.6)
+ * Processes requests to add new activity comments, and echoes HTML for a new
+ * table row.
+ *
+ * @since BuddyPress (1.6.0)
  */
 function bp_activity_admin_reply() {
 	// Check nonce
@@ -91,7 +94,7 @@ function bp_activity_admin_reply() {
 
 	// @todo: Check if user is allowed to create new activity items
 	// if ( ! current_user_can( 'bp_new_activity' ) )
-	if ( ! is_super_admin() )
+	if ( ! current_user_can( 'bp_moderate' ) )
 		die( '-1' );
 
 	// Add new activity comment
@@ -131,13 +134,15 @@ function bp_activity_admin_reply() {
 add_action( 'wp_ajax_bp-activity-admin-reply', 'bp_activity_admin_reply' );
 
 /**
- * Handle save/update of screen options for the Activity component admin screen
+ * Handle save/update of screen options for the Activity component admin screen.
+ *
+ * @since BuddyPress (1.6.0)
  *
- * @param string $value Will always be false unless another plugin filters it first.
- * @param string $option Screen option name
- * @param string $new_value Screen option form value
+ * @param string $value Will always be false unless another plugin filters it
+ *        first.
+ * @param string $option Screen option name.
+ * @param string $new_value Screen option form value.
  * @return string Option value. False to abandon update.
- * @since BuddyPress (1.6)
  */
 function bp_activity_admin_screen_options( $value, $option, $new_value ) {
 	if ( 'toplevel_page_bp_activity_per_page' != $option && 'toplevel_page_bp_activity_network_per_page' != $option )
@@ -152,11 +157,12 @@ function bp_activity_admin_screen_options( $value, $option, $new_value ) {
 }
 
 /**
- * Hide the advanced edit meta boxes by default, so we don't clutter the scren.
+ * Hide the advanced edit meta boxes by default, so we don't clutter the screen.
+ *
+ * @since BuddyPress (1.6.0)
  *
- * @param WP_Screen $screen Screen identifier
- * @return array Hidden Meta Boxes
- * @since BuddyPress (1.0)
+ * @param WP_Screen $screen Screen identifier.
+ * @return array Hidden Meta Boxes.
  */
 function bp_activity_admin_edit_hidden_metaboxes( $hidden, $screen ) {
 	if ( empty( $screen->id ) || 'toplevel_page_bp-activity' != $screen->id && 'toplevel_page_bp-activity_network' != $screen->id )
@@ -170,14 +176,22 @@ function bp_activity_admin_edit_hidden_metaboxes( $hidden, $screen ) {
 add_filter( 'default_hidden_meta_boxes', 'bp_activity_admin_edit_hidden_metaboxes', 10, 2 );
 
 /**
- * Set up the admin page before any output is sent. Register contextual help and screen options for this admin page.
+ * Set up the Activity admin page.
  *
- * @global object $bp BuddyPress global settings
- * @global BP_Activity_List_Table $bp_activity_list_table Activity screen list table
- * @since BuddyPress (1.6)
+ * Does the following:
+ *   - Register contextual help and screen options for this admin page.
+ *   - Enqueues scripts and styles
+ *   - Catches POST and GET requests related to Activity
+ *
+ * @since BuddyPress (1.6.0)
+ *
+ * @global object $bp BuddyPress global settings.
+ * @global BP_Activity_List_Table $bp_activity_list_table Activity screen list table.
  */
 function bp_activity_admin_load() {
-	global $bp, $bp_activity_list_table;
+	global $bp_activity_list_table;
+
+	$bp = buddypress();
 
 	// Decide whether to load the dev version of the CSS and JavaScript
 	$min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : 'min.';
@@ -206,7 +220,7 @@ function bp_activity_admin_load() {
 			'title'   => __( 'Item, Link, Type', 'buddypress' ),
 			'content' =>
 				'<p>' . __( '<strong>Primary Item/Secondary Item</strong> - These identify the object that created the activity. For example, the fields could reference a comment left on a specific site. Some types of activity may only use one, or none, of these fields.', 'buddypress' ) . '</p>' .
-				'<p>' . __( '<strong>Link</strong> - Activity generated by blog posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item. Some types of activity may not use this field, even if it has been set.', 'buddypress' ) . '</p>' .
+				'<p>' . __( '<strong>Link</strong> - Activity generated by posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item. Some types of activity may not use this field, even if it has been set.', 'buddypress' ) . '</p>' .
 				'<p>' . __( '<strong>Type</strong> - Each distinct kind of activity has its own type. For example, <code>created_group</code> is used when a group is created and <code>joined_group</code> is used when a user joins a group.', 'buddypress' ) . '</p>' .
 				'<p>' . __( 'For information about when and how BuddyPress uses all of these settings, see the Managing Activity link in the panel to the side.', 'buddypress' ) . '</p>'
 		) );
@@ -264,8 +278,11 @@ function bp_activity_admin_load() {
 	}
 
 	// Enqueue CSS and JavaScript
-	wp_enqueue_script( 'bp_activity_admin_js', BP_PLUGIN_URL . "bp-activity/admin/js/admin.{$min}js",   array( 'jquery', 'wp-ajax-response' ), bp_get_version(), true );
-	wp_enqueue_style( 'bp_activity_admin_css', BP_PLUGIN_URL . "bp-activity/admin/css/admin.{$min}css", array(),                               bp_get_version()       );
+	wp_enqueue_script( 'bp_activity_admin_js', $bp->plugin_url . "bp-activity/admin/js/admin.{$min}js",   array( 'jquery', 'wp-ajax-response' ), bp_get_version(), true );
+	wp_localize_script( 'bp_activity_admin_js', 'bp_activity_admin_vars', array(
+ 	  	'page'   => get_current_screen()->id
+ 	) );
+	wp_enqueue_style( 'bp_activity_admin_css', $bp->plugin_url . "bp-activity/admin/css/admin.{$min}css", array(),                               bp_get_version()       );
 
 	// Handle spam/un-spam/delete of activities
 	if ( !empty( $doaction ) && ! in_array( $doaction, array( '-1', 'edit', 'save', ) ) ) {
@@ -441,22 +458,12 @@ function bp_activity_admin_load() {
 
 		// 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
@@ -521,9 +528,9 @@ function bp_activity_admin_load() {
 }
 
 /**
- * Outputs the Activity component admin screens
+ * Output the Activity component admin screens.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 function bp_activity_admin() {
 	// Decide whether to load the index or edit screen
@@ -539,10 +546,9 @@ function bp_activity_admin() {
 }
 
 /**
- * Display the single activity edit screen
+ * Display the single activity edit screen.
  *
- * @global int $screen_layout_columns Number of columns shown on this admin page
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 function bp_activity_admin_edit() {
 
@@ -631,10 +637,11 @@ function bp_activity_admin_edit() {
 }
 
 /**
- * Status metabox for the Activity admin edit screen
+ * Status metabox for the Activity admin edit screen.
  *
- * @param object $item Activity item
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @param object $item Activity item.
  */
 function bp_activity_admin_edit_metabox_status( $item ) {
 ?>
@@ -686,26 +693,28 @@ function bp_activity_admin_edit_metabox_status( $item ) {
 }
 
 /**
- * Primary link metabox for the Activity admin edit screen
+ * Primary link metabox for the Activity admin edit screen.
  *
- * @param object $item Activity item
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @param object $item Activity item.
  */
 function bp_activity_admin_edit_metabox_link( $item ) {
 ?>
 
 	<label class="screen-reader-text" for="bp-activities-link"><?php _e( 'Link', 'buddypress' ); ?></label>
 	<input type="url" name="bp-activities-link" value="<?php echo esc_url( $item->primary_link ); ?>" />
-	<p><?php _e( 'Activity generated by blog posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item.', 'buddypress' ); ?></p>
+	<p><?php _e( 'Activity generated by posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item.', 'buddypress' ); ?></p>
 
 <?php
 }
 
 /**
- * User ID metabox for the Activity admin edit screen
+ * User ID metabox for the Activity admin edit screen.
  *
- * @param object $item Activity item
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @param object $item Activity item.
  */
 function bp_activity_admin_edit_metabox_userid( $item ) {
 ?>
@@ -716,12 +725,44 @@ function bp_activity_admin_edit_metabox_userid( $item ) {
 <?php
 }
 
+/**
+ * Get flattened array of all registered activity actions.
+ *
+ * Format is [activity_type] => Pretty name for activity type.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return array
+ */
+function bp_activity_admin_get_activity_actions() {
+	$actions  = array();
+
+	// Walk through the registered actions, and build an array of actions/values.
+	foreach ( buddypress()->activity->actions as $action ) {
+		$action = array_values( (array) $action );
+
+		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
+	unset( $actions['friends_register_activity_action'] );
+
+	// Sort array by the human-readable value
+	natsort( $actions );
+
+	return $actions;
+}
+
 /**
  * Activity type metabox for the Activity admin edit screen
  *
- * @global object $bp BuddyPress global settings
- * @param object $item Activity item
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param object $item Activity item.
  */
 function bp_activity_admin_edit_metabox_type( $item ) {
 	global $bp;
@@ -741,7 +782,17 @@ function bp_activity_admin_edit_metabox_type( $item ) {
 	unset( $actions['friends_register_activity_action'] );
 
 	// Sort array by the human-readable value
-	natsort( $actions ); ?>
+	natsort( $actions );
+
+	// 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
+	if ( ! isset( $actions[ $selected ] ) ) {
+		_doing_it_wrong( __FUNCTION__, sprintf( __( 'This activity item has a type (%s) that is not registered using bp_activity_set_action(), so no label is available.', 'buddypress' ), $selected ), '2.0.0' );
+		$actions[ $selected ] = $selected;
+	}
+
+	?>
 
 	<select name="bp-activities-type">
 		<?php foreach ( $actions as $k => $v ) : ?>
@@ -753,10 +804,11 @@ function bp_activity_admin_edit_metabox_type( $item ) {
 }
 
 /**
- * Primary item ID/Secondary item ID metabox for the Activity admin edit screen
+ * Primary item ID/Secondary item ID metabox for the Activity admin edit screen.
  *
- * @param object $item Activity item
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @param object $item Activity item.
  */
 function bp_activity_admin_edit_metabox_itemids( $item ) {
 ?>
@@ -776,9 +828,11 @@ function bp_activity_admin_edit_metabox_itemids( $item ) {
 /**
  * Display the Activity admin index screen, which contains a list of all the activities.
  *
- * @global BP_Activity_List_Table $bp_activity_list_table Activity screen list table
- * @global string $plugin_page
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @global BP_Activity_List_Table $bp_activity_list_table Activity screen list
+ *         table.
+ * @global string $plugin_page The current plugin page.
  */
 function bp_activity_admin_index() {
 	global $bp_activity_list_table, $plugin_page;
@@ -908,48 +962,56 @@ function bp_activity_admin_index() {
 class BP_Activity_List_Table extends WP_List_Table {
 
 	/**
-	 * What type of view is being displayed? e.g. "All", "Pending", "Approved", "Spam"...
+	 * What type of view is being displayed?
 	 *
-	 * @since BuddyPress (1.6)
-	*/
+	 * e.g. "all", "pending", "approved", "spam"...
+	 *
+	 * @since BuddyPress (1.6.0)
+	 * @var string
+	 */
 	public $view = 'all';
 
 	/**
 	 * How many activity items have been marked as spam.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
+	 * @var int
 	 */
 	public $spam_count = 0;
 
 	/**
 	 * Store activity-to-user-ID mappings for use in the In Response To column.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
+	 * @var array
 	 */
 	protected $activity_user_id = array();
 
 	/**
-	 * Constructor
+	 * Constructor.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 */
 	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,
 			'plural'   => 'activities',
 			'singular' => 'activity',
+			'screen'   => get_current_screen(),
 		) );
 	}
 
 	/**
-	 * Handle filtering of data, sorting, pagination, and any other data-manipulation required prior to rendering.
+	 * Handle filtering of data, sorting, pagination, and any other data manipulation prior to rendering.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 */
 	function prepare_items() {
-		$screen = get_current_screen();
 
 		// Option defaults
 		$filter           = array();
@@ -962,7 +1024,7 @@ class BP_Activity_List_Table extends WP_List_Table {
 		$page = $this->get_pagenum();
 
 		// Set per page from the screen options
-		$per_page = $this->get_items_per_page( str_replace( '-', '_', "{$screen->id}_per_page" ) );
+		$per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) );
 
 		// Check if we're on the "Spam" view
 		if ( !empty( $_REQUEST['activity_status'] ) && 'spam' == $_REQUEST['activity_status'] ) {
@@ -1045,10 +1107,11 @@ class BP_Activity_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Get an array of all the columns on the page
+	 * Get an array of all the columns on the page.
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @return array
-	 * @since BuddyPress (1.6)
+	 * @return array Column headers.
 	 */
 	function get_column_info() {
 		$this->_column_headers = array(
@@ -1061,18 +1124,18 @@ class BP_Activity_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Displays a message on screen when no items are found (e.g. no search matches)
+	 * Display a message on screen when no items are found (e.g. no search matches).
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 */
 	function no_items() {
 		_e( 'No activities found.', 'buddypress' );
 	}
 
 	/**
-	 * Outputs the Activity data table
+	 * Output the Activity data table.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	*/
 	function display() {
 		extract( $this->_args );
@@ -1102,29 +1165,38 @@ class BP_Activity_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Generates content for a single row of the table
+	 * Generate content for a single row of the table.
 	 *
-	 * @param object $item The current item
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
+	 *
+	 * @param object $item The current item.
 	 */
 	function single_row( $item ) {
-		static $row_class = '';
+		static $even = false;
+
+		if ( $even ) {
+			$row_class = ' class="even"';
+		} else {
+			$row_class = ' class="alternate odd"';
+		}
 
-		if ( empty( $row_class ) ) {
-			$row_class = ' class="alternate"';
+		if ( 'activity_comment' === $item['type'] ) {
+			$root_id = $item['item_id'];
 		} else {
-			$row_class = '';
+			$root_id = $item['id'];
 		}
 
-		echo '<tr' . $row_class . ' id="activity-' . esc_attr( $item['id'] ) . '" data-parent_id="' . esc_attr( $item['id'] ) . '" data-root_id="' . esc_attr( $item['item_id'] ) . '">';
+		echo '<tr' . $row_class . ' id="activity-' . esc_attr( $item['id'] ) . '" data-parent_id="' . esc_attr( $item['id'] ) . '" data-root_id="' . esc_attr( $root_id ) . '">';
 		echo $this->single_row_columns( $item );
 		echo '</tr>';
+
+		$even = ! $even;
 	}
 
 	/**
 	 * Get the list of views available on this table (e.g. "all", "spam").
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 */
 	function get_views() {
 		$url_base = bp_get_admin_url( 'admin.php?page=bp-activity' ); ?>
@@ -1138,11 +1210,12 @@ class BP_Activity_List_Table extends WP_List_Table {
 	<?php
 	}
 
-		/**
-	 * Get bulk actions
+	/**
+	 * Get bulk actions.
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @return array Key/value pairs for the bulk actions dropdown
-	 * @since BuddyPress (1.6)
+	 * @return array Key/value pairs for the bulk actions dropdown.
 	 */
 	function get_bulk_actions() {
 		$actions = array();
@@ -1156,25 +1229,32 @@ class BP_Activity_List_Table extends WP_List_Table {
 	/**
 	 * Get the table column titles.
 	 *
+	 * @since BuddyPress (1.6.0)
+	 *
 	 * @see WP_List_Table::single_row_columns()
-	 * @return array
-	 * @since BuddyPress (1.6)
+	 *
+	 * @return array The columns to appear in the Activity list table.
 	 */
 	function get_columns() {
 		return array(
 			'cb'       => '<input name type="checkbox" />',
 			'author'   => __( 'Author', 'buddypress' ),
 			'comment'  => __( 'Activity', 'buddypress' ),
+			'action'   => __( 'Action', 'buddypress' ),
 			'response' => __( 'In Response To', 'buddypress' ),
 		);
 	}
 
 	/**
-	 * Get the column names for sortable columns
+	 * Get the column names for sortable columns.
+	 *
+	 * Currently, returns an empty array (no columns are sortable).
 	 *
-	 * @return array
-	 * @since BuddyPress (1.6)
-	 * @todo For this to work, BP_Activity_Activity::get() needs updating to supporting ordering by specific fields
+	 * @since BuddyPress (1.6.0)
+	 * @todo For this to work, BP_Activity_Activity::get() needs updating
+	 *       to support ordering by specific fields.
+	 *
+	 * @return array The columns that can be sorted on the Activity screen.
 	 */
 	function get_sortable_columns() {
 		return array();
@@ -1185,10 +1265,11 @@ class BP_Activity_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Markup for the "filter" part of the form (i.e. which activity type to display)
+	 * Markup for the "filter" part of the form (i.e. which activity type to display).
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @param string $which 'top' or 'bottom'
-	 * @since BuddyPress (1.6)
+	 * @param string $which 'top' or 'bottom'.
 	 */
 	function extra_tablenav( $which ) {
 		if ( 'bottom' == $which )
@@ -1217,35 +1298,60 @@ class BP_Activity_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Checkbox column
+	 * Checkbox column markup.
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @param array $item A singular item (one full row)
 	 * @see WP_List_Table::single_row_columns()
-	 * @since BuddyPress (1.6)
+	 *
+	 * @param array $item A singular item (one full row).
 	 */
 	function column_cb( $item ) {
 		printf( '<label class="screen-reader-text" for="aid-%1$d">' . __( 'Select activity item %1$d', 'buddypress' ) . '</label><input type="checkbox" name="aid[]" value="%1$d" id="aid-%1$d" />', $item['id'] );
 	}
 
 	/**
-	 * Author column
+	 * Author column markup.
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @param array $item A singular item (one full row)
 	 * @see WP_List_Table::single_row_columns()
-	 * @since BuddyPress (1.6)
+	 *
+	 * @param array $item A singular item (one full row).
 	 */
 	function column_author( $item ) {
 		echo '<strong>' . get_avatar( $item['user_id'], '32' ) . ' ' . bp_core_get_userlink( $item['user_id'] ) . '</strong>';
 	}
 
+	/**
+	 * 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.
 	 *
-	 * @param array $item A singular item (one full row)
+	 * @since BuddyPress (1.6.0)
+	 *
 	 * @see WP_List_Table::single_row_columns()
-	 * @since BuddyPress (1.6)
+	 *
+	 * @param array $item A singular item (one full row).
 	 */
 	function column_comment( $item ) {
 		// Determine what type of item (row) we're dealing with
@@ -1275,7 +1381,11 @@ class BP_Activity_List_Table extends WP_List_Table {
 
 		// 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' ) );
@@ -1297,7 +1407,7 @@ class BP_Activity_List_Table extends WP_List_Table {
 		$actions = apply_filters( 'bp_activity_admin_comment_row_actions', array_filter( $actions ), $item );
 
 		/* translators: 2: activity admin ui date/time */
-		printf( __( 'Submitted on <a href="%1$s">%2$s at %3$s</a>', 'buddypress' ), bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $item['id'] . '/', get_date_from_gmt( $item['date_recorded'], get_option( 'date_format' ) ), get_date_from_gmt( $item['date_recorded'], get_option( 'time_format' ) ) );
+		printf( __( 'Submitted on <a href="%1$s">%2$s at %3$s</a>', 'buddypress' ), bp_activity_get_permalink( $item['id'] ), get_date_from_gmt( $item['date_recorded'], get_option( 'date_format' ) ), get_date_from_gmt( $item['date_recorded'], get_option( 'time_format' ) ) );
 
 		// End timestamp
 		echo '</div>';
@@ -1313,11 +1423,13 @@ class BP_Activity_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * "In response to" column
+	 * "In response to" column markup.
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @param array $item A singular item (one full row)
 	 * @see WP_List_Table::single_row_columns()
-	 * @since BuddyPress (1.6)
+	 *
+	 * @param array $item A singular item (one full row).
 	 */
 	function column_response( $item ) {
 		// Is $item is a root activity?
@@ -1342,10 +1454,15 @@ class BP_Activity_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * A wrapper function for the BP_Activity_List_Table to get the specified activity's user ID.
+	 * Get the user id associated with a given activity item.
 	 *
-	 * @param int $activity_id Activity ID to retrieve User ID for
-	 * @since BuddyPress (1.6)
+	 * Wraps bp_activity_get_specific(), with some additional logic for
+	 * avoiding duplicate queries.
+	 *
+	 * @since BuddyPress (1.6.0)
+	 *
+	 * @param int $activity_id Activity ID to retrieve User ID for.
+	 * @return int User ID of the activity item in question.
 	 */
 	protected function get_activity_user_id( $activity_id ) {
 		// If there is an existing activity/user ID mapping, just return the user ID.
@@ -1375,11 +1492,74 @@ class BP_Activity_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Helper function to flatten all activites returned from bp_activity_get() into a single array.
+	 * 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 supported
+		} else {
+			// activity comment
+			if ( '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;
+					}
+				}
+
+			// blog post
+			} elseif ( 'new_blog_post' == $item['type'] ) {
+				if ( bp_is_active( 'blogs' ) ) {
+					bp_blogs_setup_activity_loop_globals( (object) $item );
+
+					if ( empty( buddypress()->blogs->allow_comments[$item['id']] ) ) {
+						$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
+	 * items plus their comments. This method converts it to a flat array.
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @param array $tree Source array
-	 * @return array Flattened array
-	 * @since BuddyPress (1.6)
+	 * @param array $tree Source array.
+	 * @return array Flattened array.
 	 */
 	public static function flatten_activity_array( $tree ){
 		foreach ( (array) $tree as $node ) {
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-akismet.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-akismet.php
index 61d2e3c4aef78a4187c8a73500d2fb38fcb0d3d1..9298a2d0616d2a122dd01e353070ec3738af3614 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-akismet.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-akismet.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Akismet support for BuddyPress' Activity Stream
+ * Akismet support for BuddyPress' Activity Stream.
  *
  * @package BuddyPress
  * @since BuddyPress (1.6)
@@ -10,9 +10,14 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Akismet support for the Activity component.
+ *
+ * @since BuddyPress (1.6)
+ */
 class BP_Akismet {
 	/**
-	 * The activity last marked as spam
+	 * The activity last marked as spam.
 	 *
 	 * @access protected
 	 * @var BP_Activity_Activity
@@ -21,7 +26,7 @@ class BP_Akismet {
 	protected $last_activity = null;
 
 	/**
-	 * Constructor
+	 * Constructor.
 	 *
 	 * @since BuddyPress (1.6)
 	 */
@@ -30,7 +35,7 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Hook Akismet into the activity stream
+	 * Hook Akismet into the activity stream.
 	 *
 	 * @since BuddyPress (1.6)
 	 */
@@ -64,10 +69,11 @@ class BP_Akismet {
 	 * This function lifted with love from the Akismet WordPress plugin's
 	 * akismet_comment_row_action() function. Thanks!
 	 *
-	 * @param array $actions The hover links
-	 * @param array $activity The activity for the current row being processed
-	 * @return array The hover links
 	 * @since BuddyPress (1.6)
+	 *
+	 * @param array $actions The hover links.
+	 * @param array $activity The activity for the current row being processed.
+	 * @return array The hover links.
 	 */
 	function comment_row_action( $actions, $activity ) {
 		$akismet_result = bp_activity_get_meta( $activity['id'], '_bp_akismet_result' );
@@ -110,11 +116,15 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Adds a nonce to the member profile status form, and to the reply form of each activity stream item.
-	 * This is used by Akismet to help detect spam activity.
+	 * Generate nonces for activity forms.
+	 *
+	 * These nonces appear in the member profile status form, as well as in
+	 * the reply form of each activity item. The nonces are, in turn, used
+	 * by Akismet to help detect spam activity.
 	 *
-	 * @see http://plugins.trac.wordpress.org/ticket/1232
 	 * @since BuddyPress (1.6)
+	 *
+	 * @see http://plugins.trac.wordpress.org/ticket/1232
 	 */
 	public function add_activity_stream_nonce() {
 		$form_id = '_bp_as_nonce';
@@ -130,15 +140,24 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Check the member's latest (activity) update to see if it's the item that was (just) marked as spam.
+	 * Clean up the bp_latest_update usermeta in case of spamming.
 	 *
-	 * This can't be done in BP_Akismet::check_activity() due to BP-Default's AJAX implementation; see bp_dtheme_post_update().
+	 * Run just after an update is posted, this method check to see whether
+	 * the newly created update has been marked as spam by Akismet. If so,
+	 * the cached update is cleared from the user's 'bp_latest_update'
+	 * usermeta, ensuring that it won't appear in the member header and
+	 * elsewhere in the theme.
+	 *
+	 * This can't be done in BP_Akismet::check_activity() due to the
+	 * default AJAX implementation; see bp_dtheme_post_update().
 	 *
-	 * @param string $content Activity update text
-	 * @param int $user_id User ID
-	 * @param int $activity_id Activity ID
-	 * @see bp_dtheme_post_update()
 	 * @since BuddyPress (1.6)
+	 *
+	 * @see bp_dtheme_post_update()
+	 *
+	 * @param string $content Activity update text.
+	 * @param int $user_id User ID.
+	 * @param int $activity_id Activity ID.
 	 */
 	public function check_member_activity_update( $content, $user_id, $activity_id ) {
 		// By default, only handle activity updates and activity comments.
@@ -211,22 +230,25 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Get a list of filterable types of activity item that we want Akismet to automatically check for spam.
+	 * Get a filterable list of activity types that Akismet should automatically check for spam.
 	 *
-	 * @return array List of activity types
 	 * @since BuddyPress (1.6)
+	 *
 	 * @static
+	 *
+	 * @return array List of activity types.
 	 */
 	public static function get_activity_types() {
 		return apply_filters( 'bp_akismet_get_activity_types', array( 'activity_comment', 'activity_update' ) );
 	}
 
 	/**
-	 * Mark activity item as spam
+	 * Mark activity item as spam.
+	 *
+	 * @since BuddyPress (1.6)
 	 *
 	 * @param BP_Activity_Activity $activity
 	 * @param string $source Either "by_a_person" (e.g. a person has manually marked the activity as spam) or "by_akismet" (automatically spammed).
-	 * @since BuddyPress (1.6)
 	 */
 	public function mark_as_spam( $activity, $source ) {
 		// Record this item so we can do some tidyup in BP_Akismet::check_member_activity_update()
@@ -236,11 +258,12 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Mark activity item as ham
+	 * Mark activity item as ham.
+	 *
+	 * @since BuddyPress (1.6)
 	 *
 	 * @param BP_Activity_Activity $activity
 	 * @param string $source Either "by_a_person" (e.g. a person has manually marked the activity as ham) or "by_akismet" (automatically hammed).
-	 * @since BuddyPress (1.6)
 	 */
 	public function mark_as_ham( $activity, $source ) {
 		// If the activity was, originally, automatically marked as spam by Akismet, run the @mentions filter as it would have been skipped.
@@ -251,12 +274,14 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Build a data package for the Akismet service to inspect
+	 * Build a data package for the Akismet service to inspect.
 	 *
-	 * @param BP_Activity_Activity $activity
-	 * @see http://akismet.com/development/api/#comment-check
 	 * @since BuddyPress (1.6)
+	 *
+	 * @see http://akismet.com/development/api/#comment-check
 	 * @static
+	 *
+	 * @param BP_Activity_Activity $activity Activity item data.
 	 */
 	public static function build_akismet_data_package( $activity ) {
 		$userdata = get_userdata( $activity->user_id );
@@ -290,13 +315,15 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Check if the activity item is spam or ham
+	 * Check if the activity item is spam or ham.
 	 *
-	 * @param BP_Activity_Activity $activity The activity item to check
-	 * @see http://akismet.com/development/api/
 	 * @since BuddyPress (1.6)
+	 *
+	 * @see http://akismet.com/development/api/
 	 * @todo Spam counter?
 	 * @todo Auto-delete old spam?
+	 *
+	 * @param BP_Activity_Activity $activity The activity item to check.
 	 */
 	public function check_activity( $activity ) {
 		// By default, only handle activity updates and activity comments.
@@ -332,10 +359,11 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Update activity meta after a manual spam change (user initiated)
+	 * Update activity meta after a manual spam change (user-initiated).
 	 *
-	 * @param BP_Activity_Activity $activity The activity to check
 	 * @since BuddyPress (1.6)
+	 *
+	 * @param BP_Activity_Activity $activity The activity to check.
 	 */
 	public function update_activity_spam_meta( $activity ) {
 		// By default, only handle activity updates and activity comments.
@@ -348,10 +376,11 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Update activity meta after a manual ham change (user initiated)
+	 * Update activity meta after a manual ham change (user-initiated).
 	 *
-	 * @param BP_Activity_Activity $activity The activity to check
 	 * @since BuddyPress (1.6)
+	 *
+	 * @param BP_Activity_Activity $activity The activity to check.
 	 */
 	public function update_activity_ham_meta( $activity ) {
 		// By default, only handle activity updates and activity comments.
@@ -364,10 +393,11 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Update activity meta after an automatic spam check (not user initiated)
+	 * Update activity meta after an automatic spam check (not user-initiated).
 	 *
-	 * @param BP_Activity_Activity $activity The activity to check
 	 * @since BuddyPress (1.6)
+	 *
+	 * @param BP_Activity_Activity $activity The activity to check.
 	 */
 	public function update_activity_akismet_meta( $activity ) {
 		// Check we're dealing with what was last updated by Akismet
@@ -399,16 +429,19 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Contact Akismet to check if this is spam or ham
+	 * Contact Akismet to check if this is spam or ham.
+	 *
+	 * Props to WordPress core Akismet plugin for alot of this.
 	 *
-	 * Props to WordPress core Akismet plugin for alot of this
+	 * @since BuddyPress (1.6)
 	 *
 	 * @global string $akismet_api_host
 	 * @global string $akismet_api_port
-	 * @param array $activity_data Packet of information to submit to Akismet
-	 * @param string $check "check" or "submit"
-	 * @param string $spam "spam" or "ham"
-	 * @since BuddyPress (1.6)
+	 *
+	 * @param array $activity_data Packet of information to submit to Akismet.
+	 * @param string $check "check" or "submit".
+	 * @param string $spam "spam" or "ham".
+	 * @return array $activity_data Activity data, with Akismet data added.
 	 */
 	public function send_akismet_request( $activity_data, $check = 'check', $spam = 'spam' ) {
 		global $akismet_api_host, $akismet_api_port;
@@ -477,10 +510,12 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Filters user agent when sending to Akismet.
+	 * Filters user agent when sending to Akismet to add BuddyPress info.
 	 *
-	 * @param string $user_agent
 	 * @since BuddyPress (1.6)
+	 *
+	 * @param string $user_agent User agent string, as generated by Akismet.
+	 * @return string $user_agent Modified user agent string.
 	 */
 	public function buddypress_ua( $user_agent ) {
 		$user_agent = 'BuddyPress/' . bp_get_version() . ' | Akismet/'. constant( 'AKISMET_VERSION' );
@@ -490,8 +525,9 @@ class BP_Akismet {
 	/**
 	 * Adds a "History" meta box to the activity edit screen.
 	 *
-	 * @param string $screen_action The type of screen that has been requested
 	 * @since BuddyPress (1.6)
+	 *
+	 * @param string $screen_action The type of screen that has been requested.
 	 */
 	function add_history_metabox( $screen_action ) {
 		// Only proceed if we're on the edit screen
@@ -503,12 +539,14 @@ class BP_Akismet {
 	}
 
 	/**
-	 * History meta box for the Activity admin edit screen
+	 * History meta box for the Activity admin edit screen.
 	 *
-	 * @param object $item Activity item
 	 * @since BuddyPress (1.6)
-	 * @todo Update activity meta to allow >1 record with the same key (iterate through $history).
+	 *
 	 * @see http://buddypress.trac.wordpress.org/ticket/3907
+	 * @todo Update activity meta to allow >1 record with the same key (iterate through $history).
+	 *
+	 * @param object $item Activity item.
 	 */
 	function history_metabox( $item ) {
 		$history = BP_Akismet::get_activity_history( $item->id );
@@ -522,12 +560,13 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Update an activity item's Akismet history
+	 * Update an activity item's Akismet history.
 	 *
-	 * @param int $activity_id Activity item ID
-	 * @param string $message Human-readable description of what's changed
-	 * @param string $event The type of check we were carrying out
 	 * @since BuddyPress (1.6)
+	 *
+	 * @param int $activity_id Activity item ID.
+	 * @param string $message Human-readable description of what's changed.
+	 * @param string $event The type of check we were carrying out.
 	 */
 	public function update_activity_history( $activity_id = 0, $message = '', $event = '' ) {
 		$event = array(
@@ -542,11 +581,12 @@ class BP_Akismet {
 	}
 
 	/**
-	 * Get an activity item's Akismet history
+	 * Get an activity item's Akismet history.
 	 *
-	 * @param int $activity_id Activity item ID
-	 * @return array The activity item's Akismet history
 	 * @since BuddyPress (1.6)
+	 *
+	 * @param int $activity_id Activity item ID.
+	 * @return array The activity item's Akismet history.
 	 */
 	public function get_activity_history( $activity_id = 0 ) {
 		$history = bp_activity_get_meta( $activity_id, '_bp_akismet_history' );
@@ -561,11 +601,15 @@ class BP_Akismet {
 }
 
 /**
- * Deletes old spam activity meta data, as _bp_akismet_submission meta can be large.
+ * Delete old spam activity meta data
+ *
+ * This is done as a clean-up mechanism, as _bp_akismet_submission meta can
+ * grow to be quite large.
  *
- * @global object $bp BuddyPress global settings
- * @global wpdb $wpdb WordPress database object
  * @since BuddyPress (1.6)
+ *
+ * @global object $bp BuddyPress global settings.
+ * @global wpdb $wpdb WordPress database object.
  */
 function bp_activity_akismet_delete_old_metadata() {
 	global $bp, $wpdb;
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-cache.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-cache.php
index a7e5965e550f8e72b5d1a1bc2b708fd4052df0a2..36d8805db72b4aeb4784bbb7022e53e98094d697 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-cache.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-cache.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * Functions related to the BuddyPress Activity component and the WP Cache
+ * Functions related to the BuddyPress Activity component and the WP Cache.
  *
  * @since BuddyPress (1.6)
  */
@@ -10,17 +10,14 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Slurps up activitymeta
+ * Slurp up activitymeta for a specified set of activity items.
  *
- * This function is called in two places in the BP_Groups_Group class:
- *   - in the populate() method, when single group objects are populated
- *   - in the get() method, when multiple groups are queried
+ * It grabs all activitymeta associated with all of the activity items passed
+ * in $activity_ids and adds it to the WP cache. This improves efficiency when
+ * using querying activitymeta inline.
  *
- * It grabs all groupmeta associated with all of the groups passed in $group_ids and adds it to
- * the WP cache. This improves efficiency when using groupmeta inline
- *
- * @param int|str|array $group_ids Accepts a single group_id, or a comma-separated list or array of
- *    group ids
+ * @param int|str|array $activity_ids Accepts a single activity ID, or a comma-
+ *        separated list or array of activity ids
  */
 function bp_activity_update_meta_cache( $activity_ids = false ) {
 	global $bp;
@@ -29,6 +26,7 @@ function bp_activity_update_meta_cache( $activity_ids = false ) {
 		'object_ids' 	   => $activity_ids,
 		'object_type' 	   => $bp->activity->id,
 		'object_column'    => 'activity_id',
+		'cache_group'      => 'activity_meta',
 		'meta_table' 	   => $bp->activity->table_name_meta,
 		'cache_key_prefix' => 'bp_activity_meta'
 	);
@@ -37,18 +35,27 @@ function bp_activity_update_meta_cache( $activity_ids = false ) {
 }
 
 /**
- * Clear the cache for all metadata of a given activity
+ * Clear a cached activity item when that item is updated.
+ *
+ * @since 2.0
  *
- * @param int $activity_id
+ * @param BP_Activity_Activity $activity
  */
-function bp_activity_clear_meta_cache_for_activity( $activity_id ) {
-	global $wp_object_cache;
+function bp_activity_clear_cache_for_activity( $activity ) {
+	wp_cache_delete( $activity->id, 'bp_activity' );
+}
+add_action( 'bp_activity_after_save', 'bp_activity_clear_cache_for_activity' );
 
-	if ( is_object( $wp_object_cache ) && ! empty( $wp_object_cache->cache['bp'] ) ) {
-		foreach ( $wp_object_cache->cache['bp'] as $ckey => $cvalue ) {
-			if ( 0 === strpos( $ckey, 'bp_activity_meta_' . $activity_id ) ) {
-				wp_cache_delete( $ckey, 'bp' );
-			}
-		}
+/**
+ * Clear cached data for deleted activity items.
+ *
+ * @since 2.0
+ *
+ * @param array $deleted_ids IDs of deleted activity items.
+ */
+function bp_activity_clear_cache_for_deleted_activity( $deleted_ids ) {
+	foreach ( (array) $deleted_ids as $deleted_id ) {
+		wp_cache_delete( $deleted_id, 'bp_activity' );
 	}
 }
+add_action( 'bp_activity_deleted_activities', 'bp_activity_clear_cache_for_deleted_activity' );
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-classes.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-classes.php
index 47ec54088f9a63ca7342c30cf3215960a5270779..f1e6054b12525d14744e1d723281b4af1a255b0c 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-classes.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-classes.php
@@ -9,33 +9,143 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Database interaction class for the BuddyPress activity component.
+ *
+ * Instance methods are available for creating/editing an activity,
+ * static methods for querying activities.
+ *
+ * @since BuddyPress (1.0)
+ */
 class BP_Activity_Activity {
+
+	/** Properties ************************************************************/
+
+	/**
+	 * ID of the activity item.
+	 *
+	 * @var int
+	 */
 	var $id;
+
+	/**
+	 * ID of the associated item.
+	 *
+	 * @var int
+	 */
 	var $item_id;
+
+	/**
+	 * ID of the associated secondary item.
+	 *
+	 * @var int
+	 */
 	var $secondary_item_id;
+
+	/**
+	 * ID of user associated with the activity item.
+	 *
+	 * @var int
+	 */
 	var $user_id;
+
+	/**
+	 * The primary URL for the activity in RSS feeds.
+	 *
+	 * @var string
+	 */
 	var $primary_link;
+
+	/**
+	 * BuddyPress component the activity item relates to.
+	 *
+	 * @var string
+	 */
 	var $component;
+
+	/**
+	 * Activity type, eg 'new_blog_post'.
+	 *
+	 * @var string
+	 */
 	var $type;
+
+	/**
+	 * Description of the activity, eg 'Alex updated his profile.'
+	 *
+	 * @var string
+	 */
 	var $action;
+
+	/**
+	 * The content of the activity item.
+	 *
+	 * @var string
+	 */
 	var $content;
+
+	/**
+	 * The date the activity item was recorded, in 'Y-m-d h:i:s' format.
+	 *
+	 * @var string
+	 */
 	var $date_recorded;
+
+	/**
+	 * Whether the item should be hidden in sitewide streams.
+	 *
+	 * @var int
+	 */
 	var $hide_sitewide = false;
+
+	/**
+	 * Node boundary start for activity or activity comment.
+	 *
+	 * @var int
+	 */
 	var $mptt_left;
+
+	/**
+	 * Node boundary end for activity or activity comment.
+	 *
+	 * @var int
+	 */
 	var $mptt_right;
+
+	/**
+	 * Whether this item is marked as spam.
+	 *
+	 * @var int
+	 */
 	var $is_spam;
 
-	function __construct( $id = false ) {
+	/**
+	 * Constructor method.
+	 *
+	 * @param int $id Optional. The ID of a specific activity item.
+	 */
+	public function __construct( $id = false ) {
 		if ( !empty( $id ) ) {
 			$this->id = $id;
 			$this->populate();
 		}
 	}
 
-	function populate() {
+	/**
+	 * Populate the object with data about the specific activity item.
+	 */
+	public function populate() {
 		global $wpdb, $bp;
 
-		if ( $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id = %d", $this->id ) ) ) {
+		$row = wp_cache_get( $this->id, 'bp_activity' );
+
+		if ( false === $row ) {
+			$row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id = %d", $this->id ) );
+
+			wp_cache_set( $this->id, $row, 'bp_activity' );
+		}
+
+		if ( ! empty( $row ) ) {
 			$this->id                = $row->id;
 			$this->item_id           = $row->item_id;
 			$this->secondary_item_id = $row->secondary_item_id;
@@ -50,13 +160,31 @@ class BP_Activity_Activity {
 			$this->mptt_left         = $row->mptt_left;
 			$this->mptt_right        = $row->mptt_right;
 			$this->is_spam           = $row->is_spam;
+		}
+
+		// Generate dynamic 'action' when possible
+		$action = bp_activity_generate_action_string( $this );
+		if ( false !== $action ) {
+			$this->action = $action;
+
+		// If no callback is available, use the literal string from
+		// the database row
+		} else if ( ! empty( $row->action ) ) {
+			$this->action = $row->action;
 
-			bp_activity_update_meta_cache( $this->id );
+		// Provide a fallback to avoid PHP notices
+		} else {
+			$this->action = '';
 		}
 	}
 
-	function save() {
-		global $wpdb, $bp, $current_user;
+	/**
+	 * Save the activity item to the database.
+	 *
+	 * @return bool True on success.
+	 */
+	public function save() {
+		global $wpdb, $bp;
 
 		$this->id                = apply_filters_ref_array( 'bp_activity_id_before_save',                array( $this->id,                &$this ) );
 		$this->item_id           = apply_filters_ref_array( 'bp_activity_item_id_before_save',           array( $this->item_id,           &$this ) );
@@ -104,15 +232,47 @@ class BP_Activity_Activity {
 		return true;
 	}
 
-	// Static Functions
+	/** Static Methods ***************************************************/
 
 	/**
 	 * Get activity items, as specified by parameters
 	 *
-	 * @param array $args See $defaults for explanation of arguments
-	 * @return array
+	 * @see BP_Activity_Activity::get_filter_sql() for a description of the
+	 *      'filter' parameter.
+	 * @see WP_Meta_Query::queries for a description of the 'meta_query'
+	 *      parameter format.
+	 *
+	 * @param array $args {
+	 *     An array of arguments. All items are optional.
+	 *     @type int $page Which page of results to fetch. Using page=1
+	 *                     without per_page will result in no pagination.
+	 *                     Default: 1.
+	 *     @type int|bool $per_page Number of results per page. Default: 25.
+	 *     @type int|bool $max Maximum number of results to return.
+	 *                         Default: false (unlimited).
+	 *     @type string $sort ASC or DESC. Default: 'DESC'.
+	 *     @type array $exclude Array of activity IDs to exclude.
+	 *                          Default: false.
+	 *     @type array $in Array of ids to limit query by (IN).
+	 *                     Default: false.
+	 *     @type array $meta_query An array of meta_query conditions.
+	 *                             See WP_Meta_Query::queries for description.
+	 *     @type array $filter See BP_Activity_Activity::get_filter_sql().
+	 *     @type string $search_terms Limit results by a search term.
+	 *                                Default: false.
+	 *     @type bool $display_comments Whether to include activity comments.
+	 *                                  Default: false.
+	 *     @type bool $show_hidden Whether to show items marked hide_sitewide.
+	 *                             Default: false.
+	 *     @type string $spam Spam status. Default: 'ham_only'.
+	 *     @type bool $update_meta_cache Whether to pre-fetch metadata for
+	 *           queried activity items. Default: true.
+	 * }
+	 * @return array The array returned has two keys:
+	 *     - 'total' is the count of located activities
+	 *     - 'activities' is an array of the located activities
 	 */
-	function get( $args = array() ) {
+	public static function get( $args = array() ) {
 		global $wpdb, $bp;
 
 		// Backward compatibility with old method of passing arguments
@@ -138,28 +298,29 @@ class BP_Activity_Activity {
 		}
 
 		$defaults = array(
-			'page'             => 1,          // The current page
-			'per_page'         => 25,         // Activity items per page
-			'max'              => false,      // Max number of items to return
-			'sort'             => 'DESC',     // ASC or DESC
-			'exclude'          => false,      // Array of ids to exclude
-			'in'               => false,      // Array of ids to limit query by (IN)
-			'meta_query'       => false,      // Filter by activitymeta
-			'filter'           => false,      // See self::get_filter_sql()
-			'search_terms'     => false,      // Terms to search by
-			'display_comments' => false,      // Whether to include activity comments
-			'show_hidden'      => false,      // Show items marked hide_sitewide
-			'spam'             => 'ham_only', // Spam status
+			'page'              => 1,          // The current page
+			'per_page'          => 25,         // Activity items per page
+			'max'               => false,      // Max number of items to return
+			'sort'              => 'DESC',     // ASC or DESC
+			'exclude'           => false,      // Array of ids to exclude
+			'in'                => false,      // Array of ids to limit query by (IN)
+			'meta_query'        => false,      // Filter by activitymeta
+			'filter'            => false,      // See self::get_filter_sql()
+			'search_terms'      => false,      // Terms to search by
+			'display_comments'  => false,      // Whether to include activity comments
+			'show_hidden'       => false,      // Show items marked hide_sitewide
+			'spam'              => 'ham_only', // Spam status
+			'update_meta_cache' => true,
 		);
 		$r = wp_parse_args( $args, $defaults );
 		extract( $r );
 
 		// Select conditions
-		$select_sql = "SELECT DISTINCT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name";
+		$select_sql = "SELECT DISTINCT a.id";
 
-		$from_sql = " FROM {$bp->activity->table_name} a LEFT JOIN {$wpdb->users} u ON a.user_id = u.ID";
+		$from_sql   = " FROM {$bp->activity->table_name} a";
 
-		$join_sql = '';
+		$join_sql   = '';
 
 		// Where conditions
 		$where_conditions = array();
@@ -214,9 +375,20 @@ class BP_Activity_Activity {
 		// Alter the query based on whether we want to show activity item
 		// comments in the stream like normal comments or threaded below
 		// the activity.
-		if ( false === $display_comments || 'threaded' === $display_comments )
+		if ( false === $display_comments || 'threaded' === $display_comments ) {
 			$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 );
+
+		// Join the where conditions together
 		$where_sql = 'WHERE ' . join( ' AND ', $where_conditions );
 
 		// Define the preferred order for indexes
@@ -235,56 +407,64 @@ class BP_Activity_Activity {
 			$index_hint_sql = '';
 		}
 
-		if ( !empty( $per_page ) && !empty( $page ) ) {
+		// Sanitize page and per_page parameters
+		$page     = absint( $page     );
+		$per_page = absint( $per_page );
 
-			// Make sure page values are absolute integers
-			$page     = absint( $page     );
-			$per_page = absint( $per_page );
+		// Filter and return true to use the legacy query structure (not recommended)
+		if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $r ) ) {
 
-			$pag_sql    = $wpdb->prepare( "LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page );
-			$activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort} {$pag_sql}", $select_sql, $from_sql, $where_sql, $sort, $pag_sql ) );
-		} else {
-			$activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}", $select_sql, $from_sql, $where_sql, $sort ) );
-		}
+			// Legacy queries joined against the user table
+			$select_sql = "SELECT DISTINCT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name";
+			$from_sql   = " FROM {$bp->activity->table_name} a LEFT JOIN {$wpdb->users} u ON a.user_id = u.ID";
 
-		$total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$index_hint_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}", $where_sql, $sort );
+			if ( ! empty( $page ) && ! empty( $per_page ) ) {
+				$pag_sql    = $wpdb->prepare( "LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page );
+				$activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort} {$pag_sql}", $select_sql, $from_sql, $where_sql, $sort, $pag_sql ) );
+			} else {
+				$activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}", $select_sql, $from_sql, $where_sql, $sort ) );
+			}
 
-		$total_activities = $wpdb->get_var( $total_activities_sql );
+		} else {
 
-		// Get the fullnames of users so we don't have to query in the loop
-		if ( bp_is_active( 'xprofile' ) && !empty( $activities ) ) {
-			$activity_user_ids = wp_list_pluck( $activities, 'user_id' );
-			$activity_user_ids = implode( ',', wp_parse_id_list( $activity_user_ids ) );
+			// Query first for activity IDs
+			$activity_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}";
 
-			if ( !empty( $activity_user_ids ) ) {
-				if ( $names = $wpdb->get_results( "SELECT user_id, value AS user_fullname FROM {$bp->profile->table_name_data} WHERE field_id = 1 AND user_id IN ({$activity_user_ids})" ) ) {
-					foreach ( (array) $names as $name )
-						$tmp_names[$name->user_id] = $name->user_fullname;
+			if ( ! empty( $per_page ) && ! empty( $page ) ) {
+				$activity_ids_sql .= $wpdb->prepare( " LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page );
+			}
 
-					foreach ( (array) $activities as $i => $activity ) {
-						if ( !empty( $tmp_names[$activity->user_id] ) )
-							$activities[$i]->user_fullname = $tmp_names[$activity->user_id];
-					}
+			$activity_ids_sql = apply_filters( 'bp_activity_paged_activities_sql', $activity_ids_sql, $r );
 
-					unset( $names );
-					unset( $tmp_names );
-				}
-			}
+			$activity_ids = $wpdb->get_col( $activity_ids_sql );
+			$activities   = self::get_activity_data( $activity_ids );
 		}
 
+		$total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$join_sql} {$where_sql}", $where_sql, $sort );
+		$total_activities     = $wpdb->get_var( $total_activities_sql );
+
+		// Get the fullnames of users so we don't have to query in the loop
+		$activities = self::append_user_fullnames( $activities );
+
 		// Get activity meta
 		$activity_ids = array();
 		foreach ( (array) $activities as $activity ) {
 			$activity_ids[] = $activity->id;
 		}
 
-		if ( !empty( $activity_ids ) ) {
+		if ( ! empty( $activity_ids ) && $update_meta_cache ) {
 			bp_activity_update_meta_cache( $activity_ids );
 		}
 
 		if ( $activities && $display_comments )
 			$activities = BP_Activity_Activity::append_comments( $activities, $spam );
 
+		// Pre-fetch data associated with activity users and other objects
+		BP_Activity_Activity::prefetch_object_data( $activities );
+
+		// Generate action strings
+		$activities = BP_Activity_Activity::generate_action_strings( $activities );
+
 		// If $max is set, only return up to the max results
 		if ( !empty( $max ) ) {
 			if ( (int) $total_activities > (int) $max )
@@ -295,7 +475,149 @@ class BP_Activity_Activity {
 	}
 
 	/**
-	 * Get the SQL for the 'meta_query' param in BP_Activity_Activity::get()
+	 * Convert activity IDs to activity objects, as expected in template loop.
+	 *
+	 * @since 2.0
+	 *
+	 * @param array $activity_ids Array of activity IDs.
+	 * @return array
+	 */
+	protected static function get_activity_data( $activity_ids = array() ) {
+		global $wpdb;
+
+		// Bail if no activity ID's passed
+		if ( empty( $activity_ids ) ) {
+			return array();
+		}
+
+		// Get BuddyPress
+		$bp = buddypress();
+
+		$activities   = array();
+		$uncached_ids = bp_get_non_cached_ids( $activity_ids, 'bp_activity' );
+
+		// Prime caches as necessary
+		if ( ! empty( $uncached_ids ) ) {
+			// Format the activity ID's for use in the query below
+			$uncached_ids_sql = implode( ',', wp_parse_id_list( $uncached_ids ) );
+
+			// Fetch data from activity table, preserving order
+			$queried_adata = $wpdb->get_results( "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$uncached_ids_sql})");
+
+			// Put that data into the placeholders created earlier,
+			// and add it to the cache
+			foreach ( (array) $queried_adata as $adata ) {
+				wp_cache_set( $adata->id, $adata, 'bp_activity' );
+			}
+		}
+
+		// Now fetch data from the cache
+		foreach ( $activity_ids as $activity_id ) {
+			$activities[] = wp_cache_get( $activity_id, 'bp_activity' );
+		}
+
+		// Then fetch user data
+		$user_query = new BP_User_Query( array(
+			'user_ids'        => wp_list_pluck( $activities, 'user_id' ),
+			'populate_extras' => false,
+		) );
+
+		// Associated located user data with activity items
+		foreach ( $activities as $a_index => $a_item ) {
+			$a_user_id = intval( $a_item->user_id );
+			$a_user    = isset( $user_query->results[ $a_user_id ] ) ? $user_query->results[ $a_user_id ] : '';
+
+			if ( !empty( $a_user ) ) {
+				$activities[ $a_index ]->user_email    = $a_user->user_email;
+				$activities[ $a_index ]->user_nicename = $a_user->user_nicename;
+				$activities[ $a_index ]->user_login    = $a_user->user_login;
+				$activities[ $a_index ]->display_name  = $a_user->display_name;
+			}
+		}
+
+		return $activities;
+	}
+
+	/**
+	 * Append xProfile fullnames to an activity array.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $activities Activities array.
+	 * @return array
+	 */
+	protected static function append_user_fullnames( $activities ) {
+		global $wpdb;
+
+		if ( bp_is_active( 'xprofile' ) && ! empty( $activities ) ) {
+			$activity_user_ids = wp_list_pluck( $activities, 'user_id' );
+
+			if ( ! empty( $activity_user_ids ) ) {
+				$fullnames = bp_core_get_user_displaynames( $activity_user_ids );
+				if ( ! empty( $fullnames ) ) {
+					foreach ( (array) $activities as $i => $activity ) {
+						if ( ! empty( $fullnames[ $activity->user_id ] ) ) {
+							$activities[ $i ]->user_fullname = $fullnames[ $activity->user_id ];
+						}
+					}
+				}
+			}
+		}
+
+		return $activities;
+	}
+
+	/**
+	 * Pre-fetch data for objects associated with activity items.
+	 *
+	 * Activity items are associated with users, and often with other
+	 * BuddyPress data objects. Here, we pre-fetch data about these
+	 * associated objects, so that inline lookups - done primarily when
+	 * building action strings - do not result in excess database queries.
+	 *
+	 * The only object data required for activity component activity types
+	 * (activity_update and activity_comment) is related to users, and that
+	 * info is fetched separately in BP_Activity_Activity::get_activity_data().
+	 * So this method contains nothing but a filter that allows other
+	 * components, such as bp-friends and bp-groups, to hook in and prime
+	 * their own caches at the beginning of an activity loop.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $activities Array of activities.
+	 */
+	protected static function prefetch_object_data( $activities ) {
+		return apply_filters( 'bp_activity_prefetch_object_data', $activities );
+	}
+
+	/**
+	 * Generate action strings for the activities located in BP_Activity_Activity::get().
+	 *
+	 * If no string can be dynamically generated for a given item
+	 * (typically because the activity type has not been properly
+	 * registered), the static 'action' value pulled from the database will
+	 * be left in place.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $activities Array of activities.
+	 * @return array
+	 */
+	protected static function generate_action_strings( $activities ) {
+		foreach ( $activities as $key => $activity ) {
+			$generated_action = bp_activity_generate_action_string( $activity );
+			if ( false !== $generated_action ) {
+				$activity->action = $generated_action;
+			}
+
+			$activities[ $key ] = $activity;
+		}
+
+		return $activities;
+	}
+
+	/**
+	 * Get the SQL for the 'meta_query' param in BP_Activity_Activity::get().
 	 *
 	 * We use WP_Meta_Query to do the heavy lifting of parsing the
 	 * meta_query array and creating the necessary SQL clauses. However,
@@ -307,7 +629,7 @@ class BP_Activity_Activity {
 	 *
 	 * @param array $meta_query An array of meta_query filters. See the
 	 *   documentation for WP_Meta_Query for details.
-	 * @return array $sql_array 'join' and 'where' clauses
+	 * @return array $sql_array 'join' and 'where' clauses.
 	 */
 	public static function get_meta_query_sql( $meta_query = array() ) {
 		global $wpdb;
@@ -336,10 +658,14 @@ class BP_Activity_Activity {
 
 	/**
 	 * In BuddyPress 1.2.x, this was used to retrieve specific activity stream items (for example, on an activity's permalink page).
+	 *
 	 * As of 1.5.x, use BP_Activity_Activity::get() with an 'in' parameter instead.
 	 *
+	 * @since BuddyPress (1.2)
+	 *
 	 * @deprecated 1.5
 	 * @deprecated Use BP_Activity_Activity::get() with an 'in' parameter instead.
+	 *
 	 * @param mixed $activity_ids Array or comma-separated string of activity IDs to retrieve
 	 * @param int $max Maximum number of results to return. (Optional; default is no maximum)
 	 * @param int $page The set of results that the user is viewing. Used in pagination. (Optional; default is 1)
@@ -347,14 +673,26 @@ class BP_Activity_Activity {
 	 * @param string MySQL column sort; ASC or DESC. (Optional; default is DESC)
 	 * @param bool $display_comments Retrieve an activity item's associated comments or not. (Optional; default is false)
 	 * @return array
-	 * @since BuddyPress (1.2)
 	 */
-	function get_specific( $activity_ids, $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $display_comments = false ) {
+	public static function get_specific( $activity_ids, $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $display_comments = false ) {
 		_deprecated_function( __FUNCTION__, '1.5', 'Use BP_Activity_Activity::get() with the "in" parameter instead.' );
 		return BP_Activity_Activity::get( $max, $page, $per_page, $sort, false, false, $display_comments, false, false, $activity_ids );
 	}
 
-	function get_id( $user_id, $component, $type, $item_id, $secondary_item_id, $action, $content, $date_recorded ) {
+	/**
+	 * Get the first activity ID that matches a set of criteria.
+	 *
+	 * @param int $user_id The user ID to filter by.
+	 * @param string $component The component to filter by.
+	 * @param string $type The activity type to filter by.
+	 * @param int $item_id The associated item to filter by.
+	 * @param int $secondary_item_id The secondary associated item to filter by.
+	 * @param string $action The action to filter by.
+	 * @param string $content The content to filter by.
+	 * @param string $date_recorded The date to filter by.
+	 * @return int|bool Activity ID on success, false if none is found.
+	 */
+	public static function get_id( $user_id, $component, $type, $item_id, $secondary_item_id, $action, $content, $date_recorded ) {
 		global $bp, $wpdb;
 
 		$where_args = false;
@@ -391,7 +729,30 @@ class BP_Activity_Activity {
 		return $wpdb->get_var( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
 	}
 
-	function delete( $args ) {
+	/**
+	 * Delete activity items from the database.
+	 *
+	 * To delete a specific activity item, pass an 'id' parameter.
+	 * Otherwise use the filters.
+	 *
+	 * @since BuddyPress (1.2)
+	 *
+	 * @param array $args {
+	 *     @int $id Optional. The ID of a specific item to delete.
+	 *     @string $action Optional. The action to filter by.
+	 *     @string $content Optional. The content to filter by.
+	 *     @string $component Optional. The component name to filter by.
+	 *     @string $type Optional. The activity type to filter by.
+	 *     @string $primary_link Optional. The primary URL to filter by.
+	 *     @int $user_id Optional. The user ID to filter by.
+	 *     @int $item_id Optional. The associated item ID to filter by.
+	 *     @int $secondary_item_id Optional. The secondary associated item ID to filter by.
+	 *     @string $date_recorded Optional. The date to filter by.
+	 *     @int $hide_sitewide Optional. Default: false.
+	 * }
+	 * @return array|bool An array of deleted activity IDs on success, false on failure.
+	 */
+	public static function delete( $args = array() ) {
 		global $wpdb, $bp;
 
 		$defaults = array(
@@ -453,88 +814,143 @@ class BP_Activity_Activity {
 		// Fetch the activity IDs so we can delete any comments for this activity item
 		$activity_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
 
-		if ( !$wpdb->query( "DELETE FROM {$bp->activity->table_name} {$where_sql}" ) )
+		if ( ! $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$where_sql}" ) ) {
 			return false;
+		}
 
+		// Handle accompanying activity comments and meta deletion
 		if ( $activity_ids ) {
-			BP_Activity_Activity::delete_activity_item_comments( $activity_ids );
-			BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
+			$activity_ids_comma          = implode( ',', wp_parse_id_list( $activity_ids ) );
+			$activity_comments_where_sql = "WHERE type = 'activity_comment' AND item_id IN ({$activity_ids_comma})";
+
+			// Fetch the activity comment IDs for our deleted activity items
+			$activity_comment_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$activity_comments_where_sql}" );
+
+			// We have activity comments!
+			if ( ! empty( $activity_comment_ids ) ) {
+				// Delete activity comments
+				$wpdb->query( "DELETE FROM {$bp->activity->table_name} {$activity_comments_where_sql}" );
+
+				// Merge activity IDs with activity comment IDs
+				$activity_ids = array_merge( $activity_ids, $activity_comment_ids );
+			}
 
-			return $activity_ids;
+			// Delete all activity meta entries for activity items and activity comments
+			BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
 		}
 
 		return $activity_ids;
 	}
 
-	function delete_activity_item_comments( $activity_ids = array() ) {
+	/**
+	 * Delete the comments associated with a set of activity items.
+	 *
+	 * @since BuddyPress (1.2)
+	 *
+	 * @todo Mark as deprecated?  Method is no longer used internally.
+	 *
+	 * @param array $activity_ids Activity IDs whose comments should be deleted.
+	 * @param bool $delete_meta Should we delete the activity meta items for these comments?
+	 * @return bool True on success.
+	 */
+	public static function delete_activity_item_comments( $activity_ids = array(), $delete_meta = true ) {
 		global $bp, $wpdb;
 
+		$delete_meta = (bool) $delete_meta;
+
 		$activity_ids = implode( ',', wp_parse_id_list( $activity_ids ) );
 
+		if ( $delete_meta ) {
+			// Fetch the activity comment IDs for our deleted activity items
+			$activity_comment_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND item_id IN ({$activity_ids})" );
+
+			if ( ! empty( $activity_comment_ids ) ) {
+				self::delete_activity_meta_entries( $activity_comment_ids );
+			}
+		}
+
 		return $wpdb->query( "DELETE FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND item_id IN ({$activity_ids})" );
 	}
 
-	function delete_activity_meta_entries( $activity_ids = array() ) {
-		global $bp, $wpdb;
-
-		$activity_ids = implode( ',', wp_parse_id_list( $activity_ids ) );
+	/**
+	 * Delete the meta entries associated with a set of activity items.
+	 *
+	 * @since BuddyPress (1.2)
+	 *
+	 * @param array $activity_ids Activity IDs whose meta should be deleted.
+	 * @return bool True on success.
+	 */
+	public static function delete_activity_meta_entries( $activity_ids = array() ) {
+		$activity_ids = wp_parse_id_list( $activity_ids );
 
-		foreach ( (array) $activity_ids as $activity_id ) {
-			bp_activity_clear_meta_cache_for_activity( $activity_id );
+		foreach ( $activity_ids as $activity_id ) {
+			bp_activity_delete_meta( $activity_id );
 		}
 
-		return $wpdb->query( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id IN ({$activity_ids})" );
+		return true;
 	}
 
 	/**
-	 * Append activity comments to their associated activity items
+	 * Append activity comments to their associated activity items.
 	 *
-	 * @global wpdb $wpdb WordPress database object
-	 * @param array $activities
-	 * @param bool $spam Optional; 'ham_only' (default), 'spam_only' or 'all'.
-	 * @return array The updated activities with nested comments
 	 * @since BuddyPress (1.2)
+	 *
+	 * @global wpdb $wpdb WordPress database object
+	 *
+	 * @param array $activities Activities to fetch comments for.
+	 * @param bool $spam Optional. 'ham_only' (default), 'spam_only' or 'all'.
+	 * @return array The updated activities with nested comments.
 	 */
-	function append_comments( $activities, $spam = 'ham_only' ) {
-		global $wpdb;
-
+	public static function append_comments( $activities, $spam = 'ham_only' ) {
 		$activity_comments = array();
 
 		// Now fetch the activity comments and parse them into the correct position in the activities array.
-		foreach( (array) $activities as $activity ) {
+		foreach ( (array) $activities as $activity ) {
 			$top_level_parent_id = 'activity_comment' == $activity->type ? $activity->item_id : 0;
 			$activity_comments[$activity->id] = BP_Activity_Activity::get_activity_comments( $activity->id, $activity->mptt_left, $activity->mptt_right, $spam, $top_level_parent_id );
 		}
 
 		// Merge the comments with the activity items
-		foreach( (array) $activities as $key => $activity )
-			if ( isset( $activity_comments[$activity->id] ) )
+		foreach ( (array) $activities as $key => $activity ) {
+			if ( isset( $activity_comments[$activity->id] ) ) {
 				$activities[$key]->children = $activity_comments[$activity->id];
+			}
+		}
 
 		return $activities;
 	}
 
 	/**
-	 * Get activity comments that are associated with a specific activity ID
+	 * Get activity comments that are associated with a specific activity ID.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
-	 * @global wpdb $wpdb WordPress database object
-	 * @param int $activity_id Activity ID to fetch comments for
-	 * @param int $left Left-most node boundary
-	 * @param into $right Right-most node boundary
-	 * @param bool $spam Optional; 'ham_only' (default), 'spam_only' or 'all'.
-	 * @param int $top_level_parent_id The id of the root-level parent activity item
-	 * @return array The updated activities with nested comments
 	 * @since BuddyPress (1.2)
+	 *
+	 * @global BuddyPress $bp The one true BuddyPress instance.
+	 * @global wpdb $wpdb WordPress database object.
+	 *
+	 * @param int $activity_id Activity ID to fetch comments for.
+	 * @param int $left Left-most node boundary.
+	 * @param into $right Right-most node boundary.
+	 * @param bool $spam Optional. 'ham_only' (default), 'spam_only' or 'all'.
+	 * @param int $top_level_parent_id Optional. The id of the root-level parent activity item.
+	 * @return array The updated activities with nested comments.
 	 */
-	function get_activity_comments( $activity_id, $left, $right, $spam = 'ham_only', $top_level_parent_id = 0 ) {
+	public static function get_activity_comments( $activity_id, $left, $right, $spam = 'ham_only', $top_level_parent_id = 0 ) {
 		global $wpdb, $bp;
 
 		if ( empty( $top_level_parent_id ) ) {
 			$top_level_parent_id = $activity_id;
 		}
 
-		if ( !$comments = wp_cache_get( 'bp_activity_comments_' . $activity_id ) ) {
+		$comments = wp_cache_get( $activity_id, 'bp_activity_comments' );
+
+		// We store the string 'none' to cache the fact that the
+		// activity item has no comments
+		if ( 'none' === $comments ) {
+			$comments = false;
+
+		// A true cache miss
+		} else if ( empty( $comments ) ) {
 
 			// Select the user's fullname with the query
 			if ( bp_is_active( 'xprofile' ) ) {
@@ -556,12 +972,24 @@ class BP_Activity_Activity {
 				$spam_sql = '';
 			}
 
-			// The mptt BETWEEN clause allows us to limit returned descendants to the right part of the tree
-			$sql = apply_filters( 'bp_activity_comments_user_join_filter', $wpdb->prepare( "SELECT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name{$fullname_select} FROM {$bp->activity->table_name} a, {$wpdb->users} u{$fullname_from} WHERE u.ID = a.user_id {$fullname_where} AND a.type = 'activity_comment' {$spam_sql} AND a.item_id = %d AND a.mptt_left > %d AND a.mptt_left < %d ORDER BY a.date_recorded ASC", $top_level_parent_id, $left, $right ), $activity_id, $left, $right, $spam_sql );
+			// Legacy query - not recommended
+			$func_args = func_get_args();
+			if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $func_args ) ) {
+				$sql = apply_filters( 'bp_activity_comments_user_join_filter', $wpdb->prepare( "SELECT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name{$fullname_select} FROM {$bp->activity->table_name} a, {$wpdb->users} u{$fullname_from} WHERE u.ID = a.user_id {$fullname_where} AND a.type = 'activity_comment' {$spam_sql} AND a.item_id = %d AND a.mptt_left > %d AND a.mptt_left < %d ORDER BY a.date_recorded ASC", $top_level_parent_id, $left, $right ), $activity_id, $left, $right, $spam_sql );
+
+				$descendants = $wpdb->get_results( $sql );
 
-			// Retrieve all descendants of the $root node
-			$descendants = $wpdb->get_results( $sql );
-			$ref         = array();
+			// We use the mptt BETWEEN clause to limit returned
+			// descendants to the correct part of the tree.
+			} else {
+				$sql = $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} a WHERE a.type = 'activity_comment' {$spam_sql} AND a.item_id = %d and a.mptt_left > %d AND a.mptt_left < %d ORDER BY a.date_recorded ASC", $top_level_parent_id, $left, $right );
+
+				$descendant_ids = $wpdb->get_col( $sql );
+				$descendants    = self::get_activity_data( $descendant_ids );
+				$descendants    = self::append_user_fullnames( $descendants );
+			}
+
+			$ref = array();
 
 			// Loop descendants and build an assoc array
 			foreach ( (array) $descendants as $d ) {
@@ -578,13 +1006,64 @@ class BP_Activity_Activity {
 					$ref[ $d->id ] =& $comments[ $d->id ];
 				}
 			}
-			wp_cache_set( 'bp_activity_comments_' . $activity_id, $comments, 'bp' );
+
+			// Calculate depth for each item
+			foreach ( $ref as &$r ) {
+				$depth = 1;
+				$parent_id = $r->secondary_item_id;
+				while ( $parent_id !== $r->item_id ) {
+					$depth++;
+
+					// When display_comments=stream, the
+					// parent comment may not be part of
+					// the returned results, so we manually
+					// fetch it
+					if ( empty( $ref[ $parent_id ] ) ) {
+						$direct_parent = new BP_Activity_Activity( $parent_id );
+						if ( isset( $direct_parent->secondary_item_id ) ) {
+							$parent_id = $direct_parent->secondary_item_id;
+						} else {
+							// Something went wrong
+							// Short-circuit the
+							// depth calculation
+							$parent_id = $r->item_id;
+						}
+					} else {
+						$parent_id = $ref[ $parent_id ]->secondary_item_id;
+					}
+				}
+				$r->depth = $depth;
+			}
+
+			// If we cache a value of false, it'll count as a cache
+			// miss the next time the activity comments are fetched.
+			// Storing the string 'none' is a hack workaround to
+			// avoid unnecessary queries.
+			if ( false === $comments ) {
+				$cache_value = 'none';
+			} else {
+				$cache_value = $comments;
+			}
+
+			wp_cache_set( $activity_id, $cache_value, 'bp_activity_comments' );
 		}
 
 		return $comments;
 	}
 
-	function rebuild_activity_comment_tree( $parent_id, $left = 1 ) {
+	/**
+	 * Rebuild nested comment tree under an activity or activity comment.
+	 *
+	 * @since BuddyPress (1.2)
+	 *
+	 * @global BuddyPress $bp The one true BuddyPress instance.
+	 * @global wpdb $wpdb WordPress database object.
+	 *
+	 * @param int $parent_id ID of an activty or activity comment.
+	 * @param int $left Node boundary start for activity or activity comment.
+	 * @return int Right node boundary of activity or activity comment.
+	 */
+	public static function rebuild_activity_comment_tree( $parent_id, $left = 1 ) {
 		global $wpdb, $bp;
 
 		// The right value of this node is the left value + 1
@@ -608,50 +1087,89 @@ class BP_Activity_Activity {
 		return $right + 1;
 	}
 
-	function get_child_comments( $parent_id ) {
+	/**
+	 * Get child comments of an activity or activity comment.
+	 *
+	 * @since BuddyPress (1.2)
+	 *
+	 * @global BuddyPress $bp The one true BuddyPress instance.
+	 * @global wpdb $wpdb WordPress database object.
+	 *
+	 * @param int $parent_id ID of an activty or activity comment.
+	 * @return object Numerically indexed array of child comments.
+	 */
+	public static function get_child_comments( $parent_id ) {
 		global $bp, $wpdb;
 
 		return $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND secondary_item_id = %d", $parent_id ) );
 	}
 
 	/**
-	 * Fetch a list of all components that have activity items recorded
+	 * Get a list of components that have recorded activity associated with them.
 	 *
-	 * @return array
+	 * @param bool $skip_last_activity If true, components will not be
+	 *        included if the only activity type associated with them is
+	 *        'last_activity'. (Since 2.0.0, 'last_activity' is stored in
+	 *        the activity table, but these items are not full-fledged
+	 *        activity items.) Default: true.
+	 * @return array List of component names.
 	 */
-	function get_recorded_components() {
+	public static function get_recorded_components( $skip_last_activity = true ) {
 		global $wpdb, $bp;
-		return $wpdb->get_col( "SELECT DISTINCT component FROM {$bp->activity->table_name} ORDER BY component ASC" );
-	}
 
-	function get_sitewide_items_for_feed( $limit = 35 ) {
-		global $bp;
+		if ( $skip_last_activity ) {
+			$components = $wpdb->get_col( "SELECT DISTINCT component FROM {$bp->activity->table_name} WHERE action != '' AND action != 'last_activity' ORDER BY component ASC" );
+		} else {
+			$components = $wpdb->get_col( "SELECT DISTINCT component FROM {$bp->activity->table_name} ORDER BY component ASC" );
+		}
+
+		return $components;
+	}
 
+	/**
+	 * Get sitewide activity items for use in an RSS feed.
+	 *
+	 * @param int $limit Optional. Number of items to fetch. Default: 35.
+	 * @return array $activity_feed List of activity items, with RSS data added.
+	 */
+	public static function get_sitewide_items_for_feed( $limit = 35 ) {
 		$activities    = bp_activity_get_sitewide( array( 'max' => $limit ) );
 		$activity_feed = array();
 
 		for ( $i = 0, $count = count( $activities ); $i < $count; ++$i ) {
-				$title                            = explode( '<span', $activities[$i]['content'] );
-				$activity_feed[$i]['title']       = trim( strip_tags( $title[0] ) );
-				$activity_feed[$i]['link']        = $activities[$i]['primary_link'];
-				$activity_feed[$i]['description'] = @sprintf( $activities[$i]['content'], '' );
-				$activity_feed[$i]['pubdate']     = $activities[$i]['date_recorded'];
+			$title                            = explode( '<span', $activities[$i]['content'] );
+			$activity_feed[$i]['title']       = trim( strip_tags( $title[0] ) );
+			$activity_feed[$i]['link']        = $activities[$i]['primary_link'];
+			$activity_feed[$i]['description'] = @sprintf( $activities[$i]['content'], '' );
+			$activity_feed[$i]['pubdate']     = $activities[$i]['date_recorded'];
 		}
 
 		return $activity_feed;
 	}
 
-	function get_in_operator_sql( $field, $items ) {
+	/**
+	 * Create SQL IN clause for filter queries.
+	 *
+	 * @since BuddyPress (1.5)
+	 *
+	 * @see BP_Activity_Activity::get_filter_sql()
+	 *
+	 * @param string $field The database field.
+	 * @param array|bool $items The values for the IN clause, or false when none are found.
+	 */
+	public static function get_in_operator_sql( $field, $items ) {
 		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
@@ -665,7 +1183,31 @@ class BP_Activity_Activity {
 			return false;
 	}
 
-	function get_filter_sql( $filter_array ) {
+	/**
+	 * Create filter SQL clauses.
+	 *
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @param array $filter_array {
+	 *     Fields and values to filter by.
+	 *     @type array|string|id $user_id User ID(s).
+	 *     @type array|string $object Corresponds to the 'component'
+	 *           column in the database.
+	 *     @type array|string $action Corresponds to the 'type' column
+	 *           in the database.
+	 *     @type array|string|int $primary_id Corresponds to the 'item_id'
+	 *           column in the database.
+	 *     @type array|string|int $secondary_id Corresponds to the
+	 *           'secondary_item_id' column in the database.
+	 *     @type int $offset Return only those items with an ID greater
+	 *           than the offset value.
+	 *     @type string $since Return only those items that have a
+	 *           date_recorded value greater than a given MySQL-formatted
+	 *           date.
+	 * }
+	 * @return string The filter clause, for use in a SQL query.
+	 */
+	public static function get_filter_sql( $filter_array ) {
 
 		$filter_sql = array();
 
@@ -683,7 +1225,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;
 		}
 
@@ -699,32 +1241,73 @@ class BP_Activity_Activity {
 				$filter_sql[] = $sid_sql;
 		}
 
+		if ( ! empty( $filter_array['offset'] ) ) {
+			$sid_sql = absint( $filter_array['offset'] );
+			$filter_sql[] = "a.id >= {$sid_sql}";
+		}
+
+		if ( ! empty( $filter_array['since'] ) ) {
+			// Validate that this is a proper Y-m-d H:i:s date
+			// Trick: parse to UNIX date then translate back
+			$translated_date = date( 'Y-m-d H:i:s', strtotime( $filter_array['since'] ) );
+			if ( $translated_date === $filter_array['since'] ) {
+				$filter_sql[] = "a.date_recorded > '{$translated_date}'";
+			}
+		}
+
 		if ( empty( $filter_sql ) )
 			return false;
 
 		return join( ' AND ', $filter_sql );
 	}
 
-	function get_last_updated() {
+	/**
+	 * Get the date/time of last recorded activity.
+	 *
+	 * @since BuddyPress (1.2)
+	 *
+	 * @return string ISO timestamp.
+	 */
+	public static function get_last_updated() {
 		global $bp, $wpdb;
 
 		return $wpdb->get_var( "SELECT date_recorded FROM {$bp->activity->table_name} ORDER BY date_recorded DESC LIMIT 1" );
 	}
 
-	function total_favorite_count( $user_id ) {
+	/**
+	 * Get favorite count for a given user.
+	 *
+	 * @since BuddyPress (1.2)
+	 *
+	 * @param int The ID of the user whose favorites you're counting.
+	 * @return int A count of the user's favorites.
+	 */
+	public static function total_favorite_count( $user_id ) {
 		if ( !$favorite_activity_entries = bp_get_user_meta( $user_id, 'bp_favorite_activities', true ) )
 			return 0;
 
 		return count( maybe_unserialize( $favorite_activity_entries ) );
 	}
 
-	function check_exists_by_content( $content ) {
+	/**
+	 * Check whether an activity item exists with a given string content.
+	 *
+	 * @param string $content The content to filter by.
+	 * @return int|bool The ID of the first matching item if found, otherwise false.
+	 */
+	public static function check_exists_by_content( $content ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE content = %s", $content ) );
 	}
 
-	function hide_all_for_user( $user_id ) {
+	/**
+	 * Hide all activity for a given user.
+	 *
+	 * @param int $user_id The ID of the user whose activity you want to mark hidden.
+	 * @param int
+	 */
+	public static function hide_all_for_user( $user_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) );
@@ -862,6 +1445,8 @@ class BP_Activity_Feed {
 
 	/**
 	 * Setup and validate the class properties.
+	 *
+	 * @access protected
 	 */
 	protected function setup_properties() {
 		$this->id               = sanitize_title( $this->id );
@@ -874,6 +1459,7 @@ class BP_Activity_Feed {
 
 		$this->activity_args    = wp_parse_args( $this->activity_args, array(
 			'max'              => $this->max,
+			'per_page'         => $this->max,
 			'display_comments' => 'stream'
 		) );
 
@@ -884,6 +1470,8 @@ class BP_Activity_Feed {
 	 *
 	 * Currently, these hooks are used to maintain backwards compatibility with
 	 * the RSS feeds previous to BP 1.8.
+	 *
+	 * @access protected
 	 */
 	protected function setup_hooks() {
 		add_action( 'bp_activity_feed_rss_attributes',   array( $this, 'backpat_rss_attributes' ) );
@@ -893,14 +1481,23 @@ class BP_Activity_Feed {
 
 	/** BACKPAT HOOKS ********************************************************/
 
+	/**
+	 * Fire a hook to ensure backward compatibility for RSS attributes.
+	 */
 	public function backpat_rss_attributes() {
 		do_action( 'bp_activity_' . $this->id . '_feed' );
 	}
 
+	/**
+	 * Fire a hook to ensure backward compatibility for channel elements.
+	 */
 	public function backpat_channel_elements() {
 		do_action( 'bp_activity_' . $this->id . '_feed_head' );
 	}
 
+	/**
+	 * Fire a hook to ensure backward compatibility for item elements.
+	 */
 	public function backpat_item_elements() {
 		switch ( $this->id ) {
 
@@ -924,6 +1521,8 @@ class BP_Activity_Feed {
 
 	/**
 	 * Output the feed's item content.
+	 *
+	 * @access protected
 	 */
 	protected function feed_content() {
 		bp_activity_content_body();
@@ -947,12 +1546,16 @@ class BP_Activity_Feed {
 		}
 	}
 
-	/** OUTPUT ***************************************************************/
-
 	/**
-	 * Output the RSS feed.
+	 * Sets various HTTP headers related to Content-Type and browser caching.
+	 *
+	 * Most of this class method is derived from {@link WP::send_headers()}.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @access protected
 	 */
-	protected function output() {
+	protected function http_headers() {
 		// set up some additional headers if not on a directory page
 		// this is done b/c BP uses pseudo-pages
 		if ( ! bp_is_directory() ) {
@@ -962,7 +1565,72 @@ class BP_Activity_Feed {
 			status_header( 200 );
 		}
 
-		header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
+		// Set content-type
+		@header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
+
+		// Cache-related variables
+		$last_modified      = mysql2date( 'D, d M Y H:i:s O', bp_activity_get_last_updated(), false );
+		$modified_timestamp = strtotime( $last_modified );
+		$etag               = md5( $last_modified );
+
+		// Set cache-related headers
+		@header( 'Last-Modified: ' . $last_modified );
+		@header( 'Pragma: no-cache' );
+		@header( 'ETag: ' . '"' . $etag . '"' );
+
+		// First commit of BuddyPress! (Easter egg)
+		@header( 'Expires: Tue, 25 Mar 2008 17:13:55 GMT');
+
+		// Get ETag from supported user agents
+		if ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ) {
+			$client_etag = wp_unslash( $_SERVER['HTTP_IF_NONE_MATCH'] );
+
+			// Remove quotes from ETag
+			$client_etag = trim( $client_etag, '"' );
+
+			// Strip suffixes from ETag if they exist (eg. "-gzip")
+			if ( $etag_suffix_pos = strpos( $client_etag, '-' ) ) {
+				$client_etag = substr( $client_etag, 0, $etag_suffix_pos );
+			}
+
+		// No ETag found
+		} else {
+			$client_etag = false;
+		}
+
+		// Get client last modified timestamp from supported user agents
+		$client_last_modified      = empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ? '' : trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
+		$client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0;
+
+		// Set 304 status if feed hasn't been updated since last fetch
+		if ( ( $client_last_modified && $client_etag ) ?
+				 ( ( $client_modified_timestamp >= $modified_timestamp ) && ( $client_etag == $etag ) ) :
+				 ( ( $client_modified_timestamp >= $modified_timestamp ) || ( $client_etag == $etag ) ) ) {
+			$status = 304;
+		} else {
+			$status = false;
+		}
+
+		// If feed hasn't changed as reported by the user agent, set 304 status header
+		if ( ! empty( $status ) ) {
+			status_header( $status );
+
+			// cached response, so stop now!
+			if ( $status == 304 ) {
+				exit();
+			}
+		}
+	}
+
+	/** OUTPUT ***************************************************************/
+
+	/**
+	 * Output the RSS feed.
+	 *
+	 * @access protected
+	 */
+	protected function output() {
+		$this->http_headers();
 		echo '<?xml version="1.0" encoding="' . get_option( 'blog_charset' ) . '"?'.'>';
 	?>
 
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-filters.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-filters.php
index a3dfeb02ba94dafbefcf9d87ff3b3771c33d4403..9c6e5d9c7ab7ce5c97a443e5c5222271f84283a6 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-filters.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-filters.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * The Activity filters
+ * Filters related to the Activity component.
  *
  * @package BuddyPress
  * @subpackage ActivityFilters
@@ -67,18 +67,18 @@ add_filter( 'bp_get_activity_latest_update',         'make_clickable', 9 );
 add_filter( 'bp_get_activity_latest_update_excerpt', 'make_clickable', 9 );
 add_filter( 'bp_get_activity_feed_item_description', 'make_clickable', 9 );
 
-add_filter( 'bp_acomment_name',                      'stripslashes_deep' );
-add_filter( 'bp_get_activity_action',                'stripslashes_deep' );
-add_filter( 'bp_get_activity_content',               'stripslashes_deep' );
-add_filter( 'bp_get_activity_content_body',          'stripslashes_deep' );
-add_filter( 'bp_get_activity_parent_content',        'stripslashes_deep' );
-add_filter( 'bp_get_activity_latest_update',         'stripslashes_deep' );
-add_filter( 'bp_get_activity_latest_update_excerpt', 'stripslashes_deep' );
-add_filter( 'bp_get_activity_feed_item_description', 'stripslashes_deep' );
+add_filter( 'bp_acomment_name',                      'stripslashes_deep', 5 );
+add_filter( 'bp_get_activity_action',                'stripslashes_deep', 5 );
+add_filter( 'bp_get_activity_content',               'stripslashes_deep', 5 );
+add_filter( 'bp_get_activity_content_body',          'stripslashes_deep', 5 );
+add_filter( 'bp_get_activity_parent_content',        'stripslashes_deep', 5 );
+add_filter( 'bp_get_activity_latest_update',         'stripslashes_deep', 5 );
+add_filter( 'bp_get_activity_latest_update_excerpt', 'stripslashes_deep', 5 );
+add_filter( 'bp_get_activity_feed_item_description', 'stripslashes_deep', 5 );
 
 add_filter( 'bp_activity_primary_link_before_save',  'esc_url_raw' );
 
-// Apply BuddyPress defined filters
+// Apply BuddyPress-defined filters
 add_filter( 'bp_get_activity_content',               'bp_activity_make_nofollow_filter' );
 add_filter( 'bp_get_activity_content_body',          'bp_activity_make_nofollow_filter' );
 add_filter( 'bp_get_activity_parent_content',        'bp_activity_make_nofollow_filter' );
@@ -108,9 +108,11 @@ add_action( 'bp_activity_before_save', 'bp_activity_check_blacklist_keys',  2, 1
 /** Functions *****************************************************************/
 
 /**
- * Types of activity stream items to check against
+ * Types of activity stream items to moderate.
  *
  * @since BuddyPress (1.6)
+ *
+ * @return array $types List of the activity types to moderate.
  */
 function bp_activity_get_moderated_activity_types() {
 	$types = array(
@@ -121,10 +123,11 @@ function bp_activity_get_moderated_activity_types() {
 }
 
 /**
- * Check activity stream for moderation keys
+ * Moderate the posted activity item, if it contains moderate keywords.
  *
  * @since BuddyPress (1.6)
- * @param BP_Activity_Activity $activity
+ *
+ * @param BP_Activity_Activity $activity The activity object to check.
  */
 function bp_activity_check_moderation_keys( $activity ) {
 
@@ -139,10 +142,11 @@ function bp_activity_check_moderation_keys( $activity ) {
 }
 
 /**
- * Check activity stream for blacklisted keys
+ * Mark the posted activity as spam, if it contains blacklist keywords.
  *
  * @since BuddyPress (1.6)
- * @param BP_Activity_Activity $activity
+ *
+ * @param BP_Activity_Activity $activity The activity object to check.
  */
 function bp_activity_check_blacklist_keys( $activity ) {
 
@@ -156,16 +160,15 @@ function bp_activity_check_blacklist_keys( $activity ) {
 }
 
 /**
- * Custom kses filtering for activity content
+ * Custom kses filtering for activity content.
  *
  * @since BuddyPress (1.1)
  *
- * @param string $content The activity content
- *
  * @uses apply_filters() To call the 'bp_activity_allowed_tags' hook.
  * @uses wp_kses()
  *
- * @return string $content Filtered activity content
+ * @param string $content The activity content.
+ * @return string $content Filtered activity content.
  */
 function bp_activity_filter_kses( $content ) {
 	global $allowedtags;
@@ -179,7 +182,6 @@ function bp_activity_filter_kses( $content ) {
 	$activity_allowedtags['img']           = array();
 	$activity_allowedtags['img']['src']    = array();
 	$activity_allowedtags['img']['alt']    = array();
-	$activity_allowedtags['img']['class']  = array();
 	$activity_allowedtags['img']['width']  = array();
 	$activity_allowedtags['img']['height'] = array();
 	$activity_allowedtags['img']['class']  = array();
@@ -192,17 +194,13 @@ function bp_activity_filter_kses( $content ) {
 }
 
 /**
- * Finds and links @-mentioned users in the contents of a given item.
+ * Find and link @-mentioned users in the contents of a given item.
  *
- * @since BuddyPress (1.2)
+ * @since BuddyPress (1.2.0)
  *
  * @param string $content The contents of a given item.
  * @param int $activity_id The activity id. Deprecated.
- *
- * @uses bp_activity_find_mentions()
- * @uses bp_core_get_user_domain()
- *
- * @return string $content Content filtered for mentions
+ * @return string $content Content filtered for mentions.
  */
 function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
 
@@ -218,26 +216,49 @@ function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
 	if ( empty( $usernames ) )
 		return $content;
 
+	// We don't want to link @mentions that are inside of links, so we
+	// temporarily remove them
+	$replace_count = 0;
+	$replacements = array();
+	foreach ( $usernames as $username ) {
+		// prevent @ name linking inside <a> tags
+		preg_match_all( '/(<a.*?(?!<\/a>)@' . $username . '.*?<\/a>)/', $content, $content_matches );
+		if ( ! empty( $content_matches[1] ) ) {
+			foreach ( $content_matches[1] as $replacement ) {
+				$replacements[ '#BPAN' . $replace_count ] = $replacement;
+				$content = str_replace( $replacement, '#BPAN' . $replace_count, $content );
+				$replace_count++;
+			}
+		}
+	}
+
 	// Linkify the mentions with the username
-	foreach( (array) $usernames as $user_id => $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 );
 	}
 
+	// put everything back
+	if ( ! empty( $replacements ) ) {
+		foreach ( $replacements as $placeholder => $original ) {
+			$content = str_replace( $placeholder, $original, $content );
+		}
+	}
+
 	// Return the content
 	return $content;
 }
 
 /**
- * Catch mentions in activity items before they are saved into the database.
+ * Catch mentions in an activity item before it is 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.
+ * hook to send mention notifications after the activity item is saved.
  *
  * @since BuddyPress (1.5)
  *
- * @param BP_Activity_Activity $activity
- *
  * @uses bp_activity_find_mentions()
+ *
+ * @param BP_Activity_Activity $activity
  */
 function bp_activity_at_name_filter_updates( $activity ) {
 	// Are mentions disabled?
@@ -268,15 +289,14 @@ function bp_activity_at_name_filter_updates( $activity ) {
 }
 
 /**
- * Sends emails and BP notifications for @-mentioned users in the contents of
- * an activity item.
+ * Sends emails and BP notifications for users @-mentioned in an activity item.
  *
  * @since BuddyPress (1.7)
  *
- * @param BP_Activity_Activity $activity The BP_Activity_Activity object
- *
  * @uses bp_activity_at_message_notification()
  * @uses bp_activity_update_mention_count_for_user()
+ *
+ * @param BP_Activity_Activity $activity The BP_Activity_Activity object
  */
 function bp_activity_at_name_send_emails( $activity ) {
 	// Are mentions disabled?
@@ -307,25 +327,25 @@ function bp_activity_at_name_send_emails( $activity ) {
 }
 
 /**
- * Catches links in activity text so rel=nofollow can be added
+ * Catch links in activity text so rel=nofollow can be added.
  *
  * @since BuddyPress (1.2)
  *
- * @param string $text Activity text
- *
- * @return string $text Text with rel=nofollow added to any links
+ * @param string $text Activity text.
+ * @return string $text Text with rel=nofollow added to any links.
  */
 function bp_activity_make_nofollow_filter( $text ) {
 	return preg_replace_callback( '|<a (.+?)>|i', 'bp_activity_make_nofollow_filter_callback', $text );
 }
 
 	/**
-	 * Adds rel=nofollow to a link
+	 * Add rel=nofollow to a link.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @param array $matches
 	 *
+	 * @param array $matches Items matched by preg_replace_callback() in bp_activity_make_nofollow_filter().
 	 * @return string $text Link with rel=nofollow added
 	 */
 	function bp_activity_make_nofollow_filter_callback( $matches ) {
@@ -335,21 +355,20 @@ function bp_activity_make_nofollow_filter( $text ) {
 	}
 
 /**
- * Truncates long activity entries when viewed in activity streams
+ * Truncate long activity entries when viewed in activity streams.
  *
  * @since BuddyPress (1.5)
  *
- * @param string $text The original activity entry text
- *
  * @uses bp_is_single_activity()
- * @uses apply_filters() To call the 'bp_activity_excerpt_append_text' hook
- * @uses apply_filters() To call the 'bp_activity_excerpt_length' hook
+ * @uses apply_filters() To call the 'bp_activity_excerpt_append_text' hook.
+ * @uses apply_filters() To call the 'bp_activity_excerpt_length' hook.
  * @uses bp_create_excerpt()
  * @uses bp_get_activity_id()
  * @uses bp_get_activity_thread_permalink()
- * @uses apply_filters() To call the 'bp_activity_truncate_entry' hook
+ * @uses apply_filters() To call the 'bp_activity_truncate_entry' hook.
  *
- * @return string $excerpt The truncated text
+ * @param string $text The original activity entry text.
+ * @return string $excerpt The truncated text.
  */
 function bp_activity_truncate_entry( $text ) {
 	global $activities_template;
@@ -376,3 +395,179 @@ function bp_activity_truncate_entry( $text ) {
 
 	return apply_filters( 'bp_activity_truncate_entry', $excerpt, $text, $append_text );
 }
+
+/**
+ * Include extra javascript dependencies for activity component.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @uses bp_activity_do_heartbeat() to check if heartbeat is required.
+ *
+ * @param array $js_handles The original dependencies.
+ * @return array $js_handles The new dependencies.
+ */
+function bp_activity_get_js_dependencies( $js_handles = array() ) {
+	if ( bp_activity_do_heartbeat() ) {
+		$js_handles[] = 'heartbeat';
+	}
+
+	return $js_handles;
+}
+add_filter( 'bp_core_get_js_dependencies', 'bp_activity_get_js_dependencies', 10, 1 );
+
+/**
+ * Add a just-posted classes to the most recent activity item.
+ *
+ * We use these classes to avoid pagination issues when items are loaded
+ * dynamically into the activity stream.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $classes
+ * @return string $classes
+ */
+function bp_activity_newest_class( $classes = '' ) {
+	$bp = buddypress();
+
+	if ( ! empty( $bp->activity->last_recorded ) && $bp->activity->last_recorded == bp_get_activity_date_recorded() ) {
+		$classes .= ' new-update';
+	}
+
+	$classes .= ' just-posted';
+	return $classes;
+}
+
+/**
+ * Check if Activity Heartbeat feature i on to add a timestamp class.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $classes
+ * @return string $classes
+ */
+function bp_activity_timestamp_class( $classes = '' ) {
+
+	if ( ! bp_activity_do_heartbeat() ) {
+		return $classes;
+	}
+
+	$activity_date = bp_get_activity_date_recorded();
+
+	if ( empty( $activity_date ) ) {
+		return $classes;
+	}
+	
+	$classes .= ' date-recorded-' . strtotime( $activity_date );
+
+	return $classes;
+}
+add_filter( 'bp_get_activity_css_class', 'bp_activity_timestamp_class', 9, 1 );
+
+/**
+ * Use WordPress Heartbeat API to check for latest activity update.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @uses bp_activity_get_last_updated() to get the recorded date of the last activity
+ *
+ * @param array $response
+ * @param array $data
+ * @return array $response
+ */
+function bp_activity_heartbeat_last_recorded( $response = array(), $data = array() ) {
+	$bp = buddypress();
+
+	if ( empty( $data['bp_activity_last_recorded'] ) ) {
+		return $response;
+	}
+
+	// Use the querystring argument stored in the cookie (to preserve
+	// filters), but force the offset to get only new items
+	$activity_latest_args = bp_parse_args(
+		bp_ajax_querystring( 'activity' ),
+		array( 'since' => date( 'Y-m-d H:i:s', $data['bp_activity_last_recorded'] ) ),
+		'activity_latest_args'
+	);
+
+	$newest_activities = array();
+	$last_activity_recorded = 0;
+
+	// Temporarly add a just-posted class for new activity items
+	add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
+
+	ob_start();
+	if ( bp_has_activities( $activity_latest_args ) ) {
+		while ( bp_activities() ) {
+			bp_the_activity();
+
+			$atime = strtotime( bp_get_activity_date_recorded() );
+			if ( $last_activity_recorded < $atime ) {
+				$last_activity_recorded = $atime;
+			}
+
+			bp_get_template_part( 'activity/entry' );
+		}
+	}
+
+	$newest_activities['activities']    = ob_get_contents();
+	$newest_activities['last_recorded'] = $last_activity_recorded;
+	ob_end_clean();
+
+	// Remove the temporary filter
+	remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
+
+	if ( ! empty( $newest_activities['last_recorded'] ) ) {
+		$response['bp_activity_newest_activities'] = $newest_activities;
+	}
+
+	return $response;
+}
+add_filter( 'heartbeat_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
+add_filter( 'heartbeat_nopriv_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
+
+/**
+ * Set the strings for WP HeartBeat API where needed.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $strings Localized strings.
+ * @return array $strings
+ */
+function bp_activity_heartbeat_strings( $strings = array() ) {
+
+	if ( ! bp_activity_do_heartbeat() ) {
+		return $strings;
+	}
+
+	$global_pulse = 0;
+
+	// Check whether the global heartbeat settings already exist.
+	$heartbeat_settings = apply_filters( 'heartbeat_settings', array() );
+	if ( ! empty( $heartbeat_settings['interval'] ) ) {
+		// 'Fast' is 5
+		$global_pulse = is_numeric( $heartbeat_settings['interval'] ) ? absint( $heartbeat_settings['interval'] ) : 5;
+	}
+
+	// Filter here to specify a BP-specific pulse frequency
+	$bp_activity_pulse = apply_filters( 'bp_activity_heartbeat_pulse', 15 );
+
+	/**
+	 * Use the global pulse value unless:
+	 * a. the BP-specific value has been specifically filtered, or
+	 * b. it doesn't exist (ie, BP will be the only one using the heartbeat,
+	 *    so we're responsible for enabling it)
+	 */
+	if ( has_filter( 'bp_activity_heartbeat_pulse' ) || empty( $global_pulse ) ) {
+		$pulse = $bp_activity_pulse;
+	} else {
+		$pulse = $global_pulse;
+	}
+
+	$strings = array_merge( $strings, array(
+		'newest' => __( 'Load Newest', 'buddypress' ),
+		'pulse'  => absint( $pulse ),
+	) );
+
+	return $strings;
+}
+add_filter( 'bp_core_get_js_strings', 'bp_activity_heartbeat_strings', 10, 1 );
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-functions.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-functions.php
index 361c947b39a2ce4bfbda327d0a8851ae617a203a..6e5d93b00f32f10a05fd03571548dc7548048fd7 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-functions.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-functions.php
@@ -1,9 +1,9 @@
 <?php
 
 /**
- * BuddyPress Activity Functions
+ * BuddyPress Activity Functions.
  *
- * Functions for the Activity Streams component
+ * Functions for the Activity Streams component.
  *
  * @package BuddyPress
  * @subpackage ActivityFunctions
@@ -13,13 +13,13 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Checks $bp pages global and looks for directory page
+ * Check whether the $bp global lists an activity directory page.
  *
  * @since BuddyPress (1.5)
  *
  * @global object $bp BuddyPress global settings
  *
- * @return bool True if set, False if empty
+ * @return bool True if activity directory page is found, otherwise false.
  */
 function bp_activity_has_directory() {
 	global $bp;
@@ -45,6 +45,7 @@ function bp_activity_has_directory() {
  * @since BuddyPress (1.8)
  *
  * @uses apply_filters() To call 'bp_activity_do_mentions' hook.
+ *
  * @return bool $retval True to enable mentions, false to disable.
  */
 function bp_activity_do_mentions() {
@@ -52,13 +53,12 @@ function bp_activity_do_mentions() {
 }
 
 /**
- * Searches through the content of an activity item to locate usernames,
- * designated by an @ sign.
+ * Locate usernames in an activity content string, as designated by an @ sign.
  *
  * @since BuddyPress (1.5)
  *
  * @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.
+ * @return array|bool 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/';
@@ -72,11 +72,7 @@ function bp_activity_find_mentions( $content ) {
 
 	// We've found some mentions! Check to see if users exist
 	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 );
-		}
+		$user_id = bp_activity_get_userid_from_mentionname( $username );
 
 		// user ID exists, so let's add it to our array
 		if ( ! empty( $user_id ) ) {
@@ -91,12 +87,13 @@ function bp_activity_find_mentions( $content ) {
 }
 
 /**
- * Resets a user's unread mentions list and count
+ * Reset a user's unread mentions list and count.
  *
  * @since BuddyPress (1.5)
  *
- * @param int $user_id The id of the user whose unread mentions are being reset
  * @uses bp_delete_user_meta()
+ *
+ * @param int $user_id The id of the user whose unread mentions are being reset.
  */
 function bp_activity_clear_new_mentions( $user_id ) {
 	bp_delete_user_meta( $user_id, 'bp_new_mention_count' );
@@ -113,11 +110,11 @@ function bp_activity_clear_new_mentions( $user_id ) {
  *
  * @since BuddyPress (1.5)
  *
- * @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_find_mentions()
  * @uses bp_activity_update_mention_count_for_user()
+ *
+ * @param int $activity_id The unique id for the activity item.
+ * @param string $action Can be 'delete' or 'add'. Defaults to 'add'.
  */
 function bp_activity_adjust_mention_count( $activity_id = 0, $action = 'add' ) {
 	if ( empty( $activity_id ) )
@@ -140,19 +137,19 @@ function bp_activity_adjust_mention_count( $activity_id = 0, $action = 'add' ) {
 }
 
 /**
- * Updates the mention count for the user in question.
+ * Update the mention count for a given user.
  *
  * This function should be used when you've already parsed your activity item
  * for @mentions.
  *
  * @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()
+ *
+ * @param int $user_id The user ID.
+ * @param int $activity_id The unique ID for the activity item.
+ * @param string $action 'delete' or 'add'. Default: 'add'.
  * @return bool
  */
 function bp_activity_update_mention_count_for_user( $user_id, $activity_id, $action = 'add' ) {
@@ -194,111 +191,134 @@ function bp_activity_update_mention_count_for_user( $user_id, $activity_id, $act
 }
 
 /**
- * Formats notifications related to activity
- *
- * @since BuddyPress (1.5)
- *
- * @param string $action The type of activity item. Just 'new_at_mention' for now
- * @param int $item_id The activity id
- * @param int $secondary_item_id In the case of at-mentions, this is the mentioner's id
- * @param int $total_items The total number of notifications to format
- * @param string $format 'string' to get a BuddyBar-compatible notification, 'array' otherwise
+ * Determine a user's "mentionname", the name used for that user in @-mentions.
  *
- * @uses bp_loggedin_user_domain()
- * @uses bp_get_activity_slug()
- * @uses bp_core_get_user_displayname()
- * @uses apply_filters() To call the 'bp_activity_multiple_at_mentions_notification' hook
- * @uses apply_filters() To call the 'bp_activity_single_at_mentions_notification' hook
- * @uses do_action() To call 'activity_format_notifications' hook
+ * @since BuddyPress (1.9.0)
  *
- * @return string $return Formatted @mention notification
+ * @return string User name appropriate for @-mentions.
  */
-function bp_activity_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
+function bp_activity_get_user_mentionname( $user_id ) {
+	$mentionname = '';
 
-	switch ( $action ) {
-		case 'new_at_mention':
-			$activity_id      = $item_id;
-			$poster_user_id   = $secondary_item_id;
-			$at_mention_link  = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/';
-			$at_mention_title = sprintf( __( '@%s Mentions', 'buddypress' ), bp_get_loggedin_user_username() );
-
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( 'You have %1$d new mentions', 'buddypress' ), (int) $total_items );
-				$filter = 'bp_activity_multiple_at_mentions_notification';
-			} else {
-				$user_fullname = bp_core_get_user_displayname( $poster_user_id );
-				$text =  sprintf( __( '%1$s mentioned you', 'buddypress' ), $user_fullname );
-				$filter = 'bp_activity_single_at_mentions_notification';
-			}
-		break;
+	$userdata = bp_core_get_core_userdata( $user_id );
+
+	if ( $userdata ) {
+		if ( bp_is_username_compatibility_mode() ) {
+			$mentionname = str_replace( ' ', '-', $userdata->user_login );
+		} else {
+			$mentionname = $userdata->user_nicename;
+		}
 	}
 
-	if ( 'string' == $format ) {
-		$return = apply_filters( $filter, '<a href="' . $at_mention_link . '" title="' . $at_mention_title . '">' . $text . '</a>', $at_mention_link, (int) $total_items, $activity_id, $poster_user_id );
+	return $mentionname;
+}
+
+/**
+ * Get a user ID from a "mentionname", the name used for a user in @-mentions.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return int|bool ID of the user, if one is found. Otherwise false.
+ */
+function bp_activity_get_userid_from_mentionname( $mentionname ) {
+	$user_id = false;
+
+	// In username compatibility mode, hyphens are ambiguous between
+	// actual hyphens and converted spaces.
+	//
+	// @todo There is the potential for username clashes between 'foo bar'
+	// and 'foo-bar' in compatibility mode. Come up with a system for
+	// unique mentionnames.
+	if ( bp_is_username_compatibility_mode() ) {
+		// First, try the raw username
+		$userdata = get_user_by( 'login', $mentionname );
+
+		// Doing a direct query to use proper regex. Necessary to
+		// account for hyphens + spaces in the same user_login.
+		if ( empty( $userdata ) || ! is_a( $userdata, 'WP_User' ) ) {
+			global $wpdb;
+			$regex   = esc_sql( str_replace( '-', '[ \-]', $mentionname ) );
+			$user_id = $wpdb->get_var( "SELECT ID FROM {$wpdb->users} WHERE user_login REGEXP '{$regex}'" );
+		} else {
+			$user_id = $userdata->ID;
+		}
+
+	// When username compatibility mode is disabled, the mentionname is
+	// the same as the nicename
 	} else {
-		$return = apply_filters( $filter, array(
-			'text' => $text,
-			'link' => $at_mention_link
-		), $at_mention_link, (int) $total_items, $activity_id, $poster_user_id );
+		$user_id = bp_core_get_userid_from_nicename( $mentionname );
 	}
 
-	do_action( 'activity_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
 
-	return $return;
+	return $user_id;
 }
 
 /** Actions ******************************************************************/
 
 /**
- * Sets the current action for a given activity stream location
- *
- * @since BuddyPress (1.1)
- *
- * @param string $component_id
- * @param string $key
- * @param string $value
- *
- * @global object $bp BuddyPress global settings
- * @uses apply_filters() To call the 'bp_activity_set_action' hook
- *
- * @return bool False if any param is empty, otherwise true
+ * Register an activity 'type' and its action description/callback.
+ *
+ * Activity actions are strings used to describe items in the activity stream,
+ * such as 'Joe became a registered member' or 'Bill and Susie are now
+ * friends'. Each activity type (such as 'new_member' or 'friendship_created')
+ * used by a component should be registered using this function.
+ *
+ * While it's possible to post items to the activity stream whose types are
+ * not registered using bp_activity_set_action(), it is not recommended;
+ * unregistered types will not be displayed properly in the activity admin
+ * panel, and dynamic action generation (which is essential for multilingual
+ * sites, etc) will not work.
+ *
+ * @since BuddyPress (1.1.0)
+ *
+ * @param string $component_id The unique string ID of the component.
+ * @param string $type The action type.
+ * @param string $description The action description.
+ * @param callable $format_callback Callback for formatting the action string.
+ * @return bool False if any param is empty, otherwise true.
  */
-function bp_activity_set_action( $component_id, $key, $value ) {
-	global $bp;
+function bp_activity_set_action( $component_id, $type, $description, $format_callback = false ) {
+	$bp = buddypress();
 
 	// Return false if any of the above values are not set
-	if ( empty( $component_id ) || empty( $key ) || empty( $value ) )
+	if ( empty( $component_id ) || empty( $type ) || empty( $description ) ) {
 		return false;
+	}
 
 	// Set activity action
-	if ( !isset( $bp->activity->actions ) || !is_object( $bp->activity->actions ) ) {
+	if ( ! isset( $bp->activity->actions ) || ! is_object( $bp->activity->actions ) ) {
 		$bp->activity->actions = new stdClass;
 	}
 
-	if ( !isset( $bp->activity->actions->{$component_id} ) || !is_object( $bp->activity->actions->{$component_id} ) ) {
+	// Verify callback
+	if ( ! is_callable( $format_callback ) ) {
+		$format_callback = '';
+	}
+
+	if ( ! isset( $bp->activity->actions->{$component_id} ) || ! is_object( $bp->activity->actions->{$component_id} ) ) {
 		$bp->activity->actions->{$component_id} = new stdClass;
 	}
 
-	$bp->activity->actions->{$component_id}->{$key} = apply_filters( 'bp_activity_set_action', array(
-		'key'   => $key,
-		'value' => $value
-	), $component_id, $key, $value );
+	$bp->activity->actions->{$component_id}->{$type} = apply_filters( 'bp_activity_set_action', array(
+		'key'             => $type,
+		'value'           => $description,
+		'format_callback' => $format_callback,
+	), $component_id, $type, $description, $format_callback );
 
 	return true;
 }
 
 /**
- * Retreives the current action from a component and key
+ * Retreive the current action from a component and key.
  *
  * @since BuddyPress (1.1)
  *
- * @param string $component_id
- * @param string $key
+ * @global object $bp BuddyPress global settings.
+ * @uses apply_filters() To call the 'bp_activity_get_action' hook.
  *
- * @global object $bp BuddyPress global settings
- * @uses apply_filters() To call the 'bp_activity_get_action' hook
- *
- * @return mixed False on error, action on success
+ * @param string $component_id The unique string ID of the component.
+ * @param string $key The action key.
+ * @return string|bool Action value if found, otherwise false.
  */
 function bp_activity_get_action( $component_id, $key ) {
 	global $bp;
@@ -311,10 +331,11 @@ function bp_activity_get_action( $component_id, $key ) {
 }
 
 /**
- * Fetch details of all registered activity types
+ * Fetch details of all registered activity types.
  *
- * @return array array( type => description ), ...
  * @since BuddyPress (1.7)
+ *
+ * @return array array( type => description ), ...
  */
 function bp_activity_get_types() {
 	$actions  = array();
@@ -330,25 +351,21 @@ function bp_activity_get_types() {
 	// This was a mis-named activity type from before BP 1.6
 	unset( $actions['friends_register_activity_action'] );
 
-	// This type has not been used since BP 1.0.3. It will be re-instated in a future version.
-	unset( $actions['updated_profile'] );
-
 	return apply_filters( 'bp_activity_get_types', $actions );
 }
 
 /** Favorites ****************************************************************/
 
 /**
- * Get a users favorite activity stream items
+ * Get a users favorite activity stream items.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $user_id
- *
  * @uses bp_get_user_meta()
- * @uses apply_filters() To call the 'bp_activity_get_user_favorites' hook
+ * @uses apply_filters() To call the 'bp_activity_get_user_favorites' hook.
  *
- * @return array Array of users favorite activity stream ID's
+ * @param int $user_id ID of the user whose favorites are being queried.
+ * @return array IDs of the user's favorite activity items.
  */
 function bp_activity_get_user_favorites( $user_id = 0 ) {
 
@@ -363,22 +380,21 @@ function bp_activity_get_user_favorites( $user_id = 0 ) {
 }
 
 /**
- * Add an activity stream item as a favorite for a user
+ * Add an activity stream item as a favorite for a user.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $activity_id
- * @param int $user_id
- *
  * @uses is_user_logged_in()
  * @uses bp_get_user_meta()
  * @uses bp_activity_get_meta()
  * @uses bp_update_user_meta()
  * @uses bp_activity_update_meta()
- * @uses do_action() To call the 'bp_activity_add_user_favorite' hook
- * @uses do_action() To call the 'bp_activity_add_user_favorite_fail' hook
+ * @uses do_action() To call the 'bp_activity_add_user_favorite' hook.
+ * @uses do_action() To call the 'bp_activity_add_user_favorite_fail' hook.
  *
- * @return bool True on success, false on failure
+ * @param int $activity_id ID of the activity item being favorited.
+ * @param int $user_id ID of the user favoriting the activity item.
+ * @return bool True on success, false on failure.
  */
 function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
 
@@ -390,8 +406,17 @@ function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
 	if ( empty( $user_id ) )
 		$user_id = bp_loggedin_user_id();
 
-	// Update the user's personal favorites
-	$my_favs   = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
+	$my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
+	if ( empty( $my_favs ) || ! is_array( $my_favs ) ) {
+		$my_favs = array();
+	}
+
+	// Bail if the user has already favorited this activity item
+	if ( in_array( $activity_id, $my_favs ) ) {
+		return false;
+	}
+
+	// Add to user's favorites
 	$my_favs[] = $activity_id;
 
 	// Update the total number of users who have favorited this activity
@@ -402,7 +427,7 @@ function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
 	bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs );
 
 	// Update activity meta counts
-	if ( true === bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count ) ) {
+	if ( bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count ) ) {
 
 		// Execute additional code
 		do_action( 'bp_activity_add_user_favorite', $activity_id, $user_id );
@@ -420,21 +445,20 @@ function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
 }
 
 /**
- * Remove an activity stream item as a favorite for a user
+ * Remove an activity stream item as a favorite for a user.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $activity_id
- * @param int $user_id
- *
  * @uses is_user_logged_in()
  * @uses bp_get_user_meta()
  * @uses bp_activity_get_meta()
  * @uses bp_activity_update_meta()
  * @uses bp_update_user_meta()
- * @uses do_action() To call the 'bp_activity_remove_user_favorite' hook
+ * @uses do_action() To call the 'bp_activity_remove_user_favorite' hook.
  *
- * @return bool True on success, false on failure
+ * @param int $activity_id ID of the activity item being unfavorited.
+ * @param int $user_id ID of the user unfavoriting the activity item.
+ * @return bool True on success, false on failure.
  */
 function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
 
@@ -446,9 +470,15 @@ function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
 	if ( empty( $user_id ) )
 		$user_id = bp_loggedin_user_id();
 
-	// Remove the fav from the user's favs
 	$my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
 	$my_favs = array_flip( (array) $my_favs );
+
+	// Bail if the user has not previously favorited the item
+	if ( ! isset( $my_favs[ $activity_id ] ) ) {
+		return false;
+	}
+
+	// Remove the fav from the user's favs
 	unset( $my_favs[$activity_id] );
 	$my_favs = array_unique( array_flip( $my_favs ) );
 
@@ -484,45 +514,43 @@ function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
 }
 
 /**
- * Check if activity exists by scanning content
+ * Check whether an activity item exists with a given content string.
  *
  * @since BuddyPress (1.1)
  *
- * @param string $content
- *
  * @uses BP_Activity_Activity::check_exists_by_content() {@link BP_Activity_Activity}
- * @uses apply_filters() To call the 'bp_activity_check_exists_by_content' hook
+ * @uses apply_filters() To call the 'bp_activity_check_exists_by_content' hook.
  *
- * @return bool
+ * @param string $content The content to filter by.
+ * @return int|null The ID of the located activity item. Null if none is found.
  */
 function bp_activity_check_exists_by_content( $content ) {
 	return apply_filters( 'bp_activity_check_exists_by_content', BP_Activity_Activity::check_exists_by_content( $content ) );
 }
 
 /**
- * Retrieve the last time activity was updated
+ * Retrieve the last time activity was updated.
  *
  * @since BuddyPress (1.0)
  *
  * @uses BP_Activity_Activity::get_last_updated() {@link BP_Activity_Activity}
- * @uses apply_filters() To call the 'bp_activity_get_last_updated' hook
+ * @uses apply_filters() To call the 'bp_activity_get_last_updated' hook.
  *
- * @return string Date last updated
+ * @return string Date last updated.
  */
 function bp_activity_get_last_updated() {
 	return apply_filters( 'bp_activity_get_last_updated', BP_Activity_Activity::get_last_updated() );
 }
 
 /**
- * Retrieve the number of favorite activity stream items a user has
+ * Retrieve the number of favorite activity stream items a user has.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $user_id
- *
  * @uses BP_Activity_Activity::total_favorite_count() {@link BP_Activity_Activity}
  *
- * @return int Total favorite count
+ * @param int $user_id ID of the user whose favorite count is being requested.
+ * @return int Total favorite count for the user.
  */
 function bp_activity_total_favorites_for_user( $user_id = 0 ) {
 
@@ -536,200 +564,134 @@ function bp_activity_total_favorites_for_user( $user_id = 0 ) {
 /** Meta *********************************************************************/
 
 /**
- * Delete a meta entry from the DB for an activity stream item
- *
- * @since BuddyPress (1.2)
- *
- * @param int $activity_id
- * @param string $meta_key
- * @param string $meta_value
- *
- * @global object $wpdb
- * @global object $bp BuddyPress global settings
- * @uses wp_cache_delete()
- * @uses is_wp_error()
- *
- * @return bool True on success, false on failure
+ * Delete a meta entry from the DB for an activity stream item.
+ *
+ * @since BuddyPress (1.2.0)
+ *
+ * @global object $wpdb WordPress database access object.
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param int $activity_id ID of the activity item whose metadata is being deleted.
+ * @param string $meta_key Optional. The key of the metadata being deleted. If
+ *        omitted, all metadata associated with the activity
+ *        item will be deleted.
+ * @param string $meta_value Optional. If present, the metadata will only be
+ *        deleted if the meta_value matches this parameter.
+ * @param bool $delete_all Optional. If true, delete matching metadata entries
+ * 	  for all objects, ignoring the specified object_id. Otherwise,
+ * 	  only delete matching metadata entries for the specified
+ * 	  activity item. Default: false.
+ * @return bool True on success, false on failure.
  */
-function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = '' ) {
+function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = '', $delete_all = false ) {
 	global $wpdb, $bp;
 
-	// Return false if any of the above values are not set
-	if ( !is_numeric( $activity_id ) )
-		return false;
-
-	// Sanitize key
-	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-	if ( is_array( $meta_value ) || is_object( $meta_value ) )
-		$meta_value = serialize( $meta_value );
-
-	// Trim off whitespace
-	$meta_value = trim( $meta_value );
+	// Legacy - if no meta_key is passed, delete all for the item
+	if ( empty( $meta_key ) ) {
+		$all_meta = bp_activity_get_meta( $activity_id );
+		$keys     = ! empty( $all_meta ) ? array_keys( $all_meta ) : array();
 
-	// Delete all for activity_id
-	if ( empty( $meta_key ) )
-		$retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
-
-	// Delete only when all match
-	else if ( $meta_value )
-		$retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s AND meta_value = %s", $activity_id, $meta_key, $meta_value ) );
-
-	// Delete only when activity_id and meta_key match
-	else
-		$retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
+		// With no meta_key, ignore $delete_all
+		$delete_all = false;
+	} else {
+		$keys = array( $meta_key );
+	}
 
-	// Delete cache entry
-	wp_cache_delete( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, 'bp' );
+	$retval = true;
 
-	// Success
-	if ( !is_wp_error( $retval ) )
-		return true;
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	foreach ( $keys as $key ) {
+		$retval = delete_metadata( 'activity', $activity_id, $key, $meta_value, $delete_all );
+	}
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	// Fail
-	else
-		return false;
+	return $retval;
 }
 
 /**
- * Get activity meta
+ * Get metadata for a given activity item.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $activity_id
- * @param string $meta_key
+ * @uses apply_filters() To call the 'bp_activity_get_meta' hook.
  *
- * @global object $wpdb
- * @global object $bp BuddyPress global settings
- * @uses wp_cache_get()
- * @uses wp_cache_set()
- * @uses apply_filters() To call the 'bp_activity_get_meta' hook
- *
- * @return bool
+ * @param int $activity_id ID of the activity item whose metadata is being requested.
+ * @param string $meta_key Optional. If present, only the metadata matching
+ *        that meta key will be returned. Otherwise, all metadata for the
+ *        activity item will be fetched.
+ * @param bool $single Optional. If true, return only the first value of the
+ *	  specified meta_key. This parameter has no effect if meta_key is not
+ *	  specified. Default: true.
+ * @return mixed The meta value(s) being requested.
  */
-function bp_activity_get_meta( $activity_id = 0, $meta_key = '' ) {
-	global $wpdb, $bp;
-
-	// Make sure activity_id is valid
-	if ( empty( $activity_id ) || !is_numeric( $activity_id ) )
-		return false;
-
-	// We have a key to look for
-	if ( !empty( $meta_key ) ) {
-
-		// Sanitize key
-		$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-		// Check cache
-		if ( !$metas = wp_cache_get( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, 'bp' ) ) {
-			// No cache so hit the DB
-			$metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
-
-			// Set cache
-			wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, $metas, 'bp' );
-		}
-
-	// No key so get all for activity_id
-	} else {
-		$metas = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
-
-		if ( !empty( $metas ) ) {
-			$metas = array_map( 'maybe_unserialize', (array) $metas );
-
-			foreach( $metas as $mkey => $mvalue ) {
-				wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $mkey, $mvalue, 'bp' );
-			}
-		}
-	}
-
-	// No result so return false
-	if ( empty( $metas ) )
-		return false;
-
-	// Maybe, just maybe... unserialize
-	$metas = array_map( 'maybe_unserialize', (array) $metas );
-
-	// Return first item in array if only 1, else return all metas found
-	$retval = ( 1 == count( $metas ) ? $metas[0] : $metas );
+function bp_activity_get_meta( $activity_id = 0, $meta_key = '', $single = true ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = get_metadata( 'activity', $activity_id, $meta_key, $single );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
 	// Filter result before returning
-	return apply_filters( 'bp_activity_get_meta', $retval, $activity_id, $meta_key );
+	return apply_filters( 'bp_activity_get_meta', $retval, $activity_id, $meta_key, $single );
 }
 
 /**
- * Update activity meta
+ * Update a piece of activity meta.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $activity_id
- * @param string $meta_key
- * @param string $meta_value
- *
- * @global object $wpdb
- * @global object $bp BuddyPress global settings
- * @uses maybe_serialize()
- * @uses bp_activity_delete_meta()
- * @uses wp_cache_set()
- *
- * @return bool True on success, false on failure
+ * @param int $activity_id ID of the activity item whose metadata is being
+ *        updated.
+ * @param string $meta_key Key of the metadata being updated.
+ * @param mixed $meta_value Value to be set.
+ * @param mixed $prev_value Optional. If specified, only update existing
+ *        metadata entries with the specified value. Otherwise, update all
+ *        entries.
+ * @return bool|int Returns false on failure. On successful update of existing
+ *         metadata, returns true. On successful creation of new metadata,
+ *         returns the integer ID of the new metadata row.
  */
-function bp_activity_update_meta( $activity_id, $meta_key, $meta_value ) {
-	global $wpdb, $bp;
-
-	// Make sure activity_id is valid
-	if ( !is_numeric( $activity_id ) )
-		return false;
-
-	// Sanitize key
-	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-	// Sanitize value
-	if ( is_string( $meta_value ) )
-		$meta_value = stripslashes( esc_sql( $meta_value ) );
-
-	// Maybe, just maybe... serialize
-	$meta_value = maybe_serialize( $meta_value );
-
-	// If value is empty, delete the meta key
-	if ( empty( $meta_value ) )
-		return bp_activity_delete_meta( $activity_id, $meta_key );
-
-	// See if meta key exists for activity_id
-	$cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
+function bp_activity_update_meta( $activity_id, $meta_key, $meta_value, $prev_value = '' ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = update_metadata( 'activity', $activity_id, $meta_key, $meta_value, $prev_value );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	// Meta key does not exist so INSERT
-	if ( empty( $cur ) )
-		$wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_meta} ( activity_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $activity_id, $meta_key, $meta_value ) );
-
-	// Meta key exists, so UPDATE
-	else if ( $cur->meta_value != $meta_value )
-		$wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name_meta} SET meta_value = %s WHERE activity_id = %d AND meta_key = %s", $meta_value, $activity_id, $meta_key ) );
-
-	// Weirdness, so return false
-	else
-		return false;
+	return $retval;
+}
 
-	// Set cache
-	wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, $meta_value, 'bp' );
+/**
+ * Add a piece of activity metadata.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $activity_id ID of the activity item.
+ * @param string $meta_key Metadata key.
+ * @param mixed $meta_value Metadata value.
+ * @param bool $unique. Optional. Whether to enforce a single metadata value
+ *        for the given key. If true, and the object already has a value for
+ *        the key, no change will be made. Default: false.
+ * @return int|bool The meta ID on successful update, false on failure.
+ */
+function bp_activity_add_meta( $activity_id, $meta_key, $meta_value, $unique = false ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = add_metadata( 'activity', $activity_id, $meta_key, $meta_value, $unique );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	// Victory is ours!
-	return true;
+	return $retval;
 }
 
 /** Clean up *****************************************************************/
 
 /**
- * Completely remove a user's activity data
+ * Completely remove a user's activity data.
  *
  * @since BuddyPress (1.5)
  *
- * @param int $user_id
- *
  * @uses is_user_logged_in()
  * @uses bp_activity_delete()
  * @uses bp_delete_user_meta()
- * @uses do_action() To call the 'bp_activity_remove_data' hook
- * @uses do_action() To call the 'bp_activity_remove_all_user_data' hook
+ * @uses do_action() To call the 'bp_activity_remove_data' hook.
+ * @uses do_action() To call the 'bp_activity_remove_all_user_data' hook.
+ *
+ * @param int $user_id ID of the user whose activity is being deleted.
  */
 function bp_activity_remove_all_user_data( $user_id = 0 ) {
 
@@ -754,12 +716,14 @@ add_action( 'wpmu_delete_user',  'bp_activity_remove_all_user_data' );
 add_action( 'delete_user',       'bp_activity_remove_all_user_data' );
 
 /**
- * Mark all of the user's activity as spam
+ * Mark all of the user's activity as spam.
  *
- * @global object $wpdb
- * @global object $bp BuddyPress global settings
- * @param int $user_id
  * @since BuddyPress (1.6)
+ *
+ * @global object $wpdb WordPress database access object.
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param int $user_id ID of the user whose activity is being spammed.
  */
 function bp_activity_spam_all_user_data( $user_id = 0 ) {
 	global $bp, $wpdb;
@@ -805,12 +769,14 @@ function bp_activity_spam_all_user_data( $user_id = 0 ) {
 add_action( 'bp_make_spam_user', 'bp_activity_spam_all_user_data' );
 
 /**
- * Mark all of the user's activity as ham (not spam)
+ * Mark all of the user's activity as ham (not spam).
  *
- * @global object $wpdb
- * @global object $bp BuddyPress global settings
- * @param int $user_id
  * @since BuddyPress (1.6)
+ *
+ * @global object $wpdb WordPress database access object.
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param int $user_id ID of the user whose activity is being hammed.
  */
 function bp_activity_ham_all_user_data( $user_id = 0 ) {
 	global $bp, $wpdb;
@@ -858,14 +824,26 @@ add_action( 'bp_make_ham_user', 'bp_activity_ham_all_user_data' );
 /**
  * Register the activity stream actions for updates
  *
- * @global object $bp BuddyPress global settings
  * @since BuddyPress (1.6)
+ *
+ * @global object $bp BuddyPress global settings.
  */
 function bp_activity_register_activity_actions() {
 	global $bp;
 
-	bp_activity_set_action( $bp->activity->id, 'activity_update', __( 'Posted a status update', 'buddypress' ) );
-	bp_activity_set_action( $bp->activity->id, 'activity_comment', __( 'Replied to a status update', 'buddypress' ) );
+	bp_activity_set_action(
+		$bp->activity->id,
+		'activity_update',
+		__( 'Posted a status update', 'buddypress' ),
+		'bp_activity_format_activity_action_activity_update'
+	);
+
+	bp_activity_set_action(
+		$bp->activity->id,
+		'activity_comment',
+		__( 'Replied to a status update', 'buddypress' ),
+		'bp_activity_format_activity_action_activity_comment'
+	);
 
 	do_action( 'bp_activity_register_activity_actions' );
 
@@ -874,6 +852,64 @@ function bp_activity_register_activity_actions() {
 }
 add_action( 'bp_register_activity_actions', 'bp_activity_register_activity_actions' );
 
+/**
+ * Generate an activity action string for an activity item.
+ *
+ * @param object $activity Activity data object.
+ * @return string|bool Returns false if no callback is found, otherwise returns
+ *         the formatted action string.
+ */
+function bp_activity_generate_action_string( $activity ) {
+	// Check for valid input
+	if ( empty( $activity->component ) || empty( $activity->type ) ) {
+		return false;
+	}
+
+	// Check for registered format callback
+	if ( empty( buddypress()->activity->actions->{$activity->component}->{$activity->type}['format_callback'] ) ) {
+		return false;
+	}
+
+	// We apply the format_callback as a filter
+	add_filter( 'bp_activity_generate_action_string', buddypress()->activity->actions->{$activity->component}->{$activity->type}['format_callback'], 10, 2 );
+
+	// Generate the action string (run through the filter defined above)
+	$action = apply_filters( 'bp_activity_generate_action_string', $activity->action, $activity );
+
+	// Remove the filter for future activity items
+	remove_filter( 'bp_activity_generate_action_string', buddypress()->activity->actions->{$activity->component}->{$activity->type}['format_callback'], 10, 2 );
+
+	return $action;
+}
+
+/**
+ * Format 'activity_update' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param object $activity Activity data object.
+ * @return string
+ */
+function bp_activity_format_activity_action_activity_update( $action, $activity ) {
+	$action = sprintf( __( '%s posted an update', 'buddypress' ), bp_core_get_userlink( $activity->user_id ) );
+	return apply_filters( 'bp_activity_new_update_action', $action, $activity );
+}
+
+/**
+ * Format 'activity_comment' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param object $activity Activity data object.
+ * @return string
+ */
+function bp_activity_format_activity_action_activity_comment( $action, $activity ) {
+	$action = sprintf( __( '%s posted a new activity comment', 'buddypress' ), bp_core_get_userlink( $activity->user_id ) );
+	return apply_filters( 'bp_activity_comment_action', $action, $activity );
+}
+
 /******************************************************************************
  * Business functions are where all the magic happens in BuddyPress. They will
  * handle the actual saving or manipulation of information. Usually they will
@@ -882,34 +918,42 @@ add_action( 'bp_register_activity_actions', 'bp_activity_register_activity_actio
  */
 
 /**
- * Retrieve an activity or activities
+ * Retrieve an activity or activities.
  *
- * @since BuddyPress (1.2)
+ * bp_activity_get() shares all arguments with BP_Activity_Activity::get(). The
+ * following is a list of bp_activity_get() parameters that have different
+ * default values from BP_Activity_Activity::get() (value in parentheses is
+ * the default for the bp_activity_get()).
+ *   - 'per_page' (false)
  *
- * @param array $args
+ * @since BuddyPress (1.2)
  *
+ * @see BP_Activity_Activity::get() For more information on accepted arguments
+ *      and the format of the returned value.
  * @uses wp_parse_args()
  * @uses wp_cache_get()
  * @uses wp_cache_set()
  * @uses BP_Activity_Activity::get() {@link BP_Activity_Activity}
- * @uses apply_filters_ref_array() To call the 'bp_activity_get' hook
+ * @uses apply_filters_ref_array() To call the 'bp_activity_get' hook.
  *
- * @return object $activity The activity/activities object
+ * @param array $args See BP_Activity_Activity::get() for description.
+ * @return array $activity See BP_Activity_Activity::get() for description.
  */
 function bp_activity_get( $args = '' ) {
 	$defaults = array(
-		'max'              => false,        // Maximum number of results to return
-		'page'             => 1,            // page 1 without a per_page will result in no pagination.
-		'per_page'         => false,        // results per page
-		'sort'             => 'DESC',       // sort ASC or DESC
-		'display_comments' => false,        // false for no comments. 'stream' for within stream display, 'threaded' for below each activity item
-
-		'search_terms'     => false,        // Pass search terms as a string
-		'meta_query'       => false,        // Filter by activity meta. See WP_Meta_Query for format
-		'show_hidden'      => false,        // Show activity items that are hidden site-wide?
-		'exclude'          => false,        // Comma-separated list of activity IDs to exclude
-		'in'               => false,        // Comma-separated list or array of activity IDs to which you want to limit the query
-		'spam'             => 'ham_only',   // 'ham_only' (default), 'spam_only' or 'all'.
+		'max'               => false,        // Maximum number of results to return
+		'page'              => 1,            // page 1 without a per_page will result in no pagination.
+		'per_page'          => false,        // results per page
+		'sort'              => 'DESC',       // sort ASC or DESC
+		'display_comments'  => false,        // false for no comments. 'stream' for within stream display, 'threaded' for below each activity item
+
+		'search_terms'      => false,        // Pass search terms as a string
+		'meta_query'        => false,        // Filter by activity meta. See WP_Meta_Query for format
+		'show_hidden'       => false,        // Show activity items that are hidden site-wide?
+		'exclude'           => false,        // Comma-separated list of activity IDs to exclude
+		'in'                => false,        // Comma-separated list or array of activity IDs to which you want to limit the query
+		'spam'              => 'ham_only',   // 'ham_only' (default), 'spam_only' or 'all'.
+		'update_meta_cache' => true,
 
 		/**
 		 * Pass filters as an array -- all filter items can be multiple values comma separated:
@@ -930,16 +974,17 @@ function bp_activity_get( $args = '' ) {
 	if ( 1 == (int) $page && empty( $max ) && empty( $search_terms ) && empty( $meta_query ) && empty( $filter ) && empty( $exclude ) && empty( $in ) && 'DESC' == $sort && empty( $exclude ) && 'ham_only' == $spam ) {
 		if ( !$activity = wp_cache_get( 'bp_activity_sitewide_front', 'bp' ) ) {
 			$args = array(
-				'page'             => $page,
-				'per_page'         => $per_page,
-				'max'              => $max,
-				'sort'             => $sort,
-				'search_terms'     => $search_terms,
-				'meta_query'       => $meta_query,
-				'filter'           => $filter,
-				'display_comments' => $display_comments,
-				'show_hidden'      => $show_hidden,
-				'spam'             => $spam
+				'page'              => $page,
+				'per_page'          => $per_page,
+				'max'               => $max,
+				'sort'              => $sort,
+				'search_terms'      => $search_terms,
+				'meta_query'        => $meta_query,
+				'filter'            => $filter,
+				'display_comments'  => $display_comments,
+				'show_hidden'       => $show_hidden,
+				'spam'              => $spam,
+				'update_meta_cache' => $update_meta_cache,
 			);
 			$activity = BP_Activity_Activity::get( $args );
 			wp_cache_set( 'bp_activity_sitewide_front', $activity, 'bp' );
@@ -967,59 +1012,95 @@ function bp_activity_get( $args = '' ) {
 }
 
 /**
- * Fetch specific activity items
+ * Fetch specific activity items.
  *
  * @since BuddyPress (1.2)
  *
- * @param array $args See docs for $defaults for details
- *
+ * @see BP_Activity_Activity::get() For more information on accepted arguments
  * @uses wp_parse_args()
  * @uses apply_filters() To call the 'bp_activity_get_specific' hook
  * @uses BP_Activity_Activity::get() {@link BP_Activity_Activity}
  *
- * @return array The array returned by BP_Activity_Activity::get()
+ * @param array $args {
+ *     All arguments and defaults are shared with BP_Activity_Activity::get(),
+ *     except for the following:
+ *     @type string|int|array Single activity ID, comma-separated list of IDs,
+ *           or array of IDs.
+ * }
+ * @return array $activity See BP_Activity_Activity::get() for description.
  */
 function bp_activity_get_specific( $args = '' ) {
 	$defaults = array(
-		'activity_ids'     => false,       // A single activity_id or array of IDs.
-		'display_comments' => false,       // true or false to display threaded comments for these specific activity items
-		'max'              => false,       // Maximum number of results to return
-		'page'             => 1,           // page 1 without a per_page will result in no pagination.
-		'per_page'         => false,       // results per page
-		'show_hidden'      => true,        // When fetching specific items, show all
-		'sort'             => 'DESC',      // sort ASC or DESC
-		'spam'             => 'ham_only',  // Retrieve items marked as spam
+		'activity_ids'      => false,       // A single activity_id or array of IDs.
+		'display_comments'  => false,       // true or false to display threaded comments for these specific activity items
+		'max'               => false,       // Maximum number of results to return
+		'page'              => 1,           // page 1 without a per_page will result in no pagination.
+		'per_page'          => false,       // results per page
+		'show_hidden'       => true,        // When fetching specific items, show all
+		'sort'              => 'DESC',      // sort ASC or DESC
+		'spam'              => 'ham_only',  // Retrieve items marked as spam
+		'update_meta_cache' => true,
 	);
 	$r = wp_parse_args( $args, $defaults );
 	extract( $r, EXTR_SKIP );
 
 	$get_args = array(
-		'page'             => $page,
-		'per_page'         => $per_page,
-		'max'              => $max,
-		'sort'             => $sort,
-		'display_comments' => $display_comments,
-		'show_hidden'      => $show_hidden,
-		'in'               => $activity_ids,
-		'spam'             => $spam
+		'page'              => $page,
+		'per_page'          => $per_page,
+		'max'               => $max,
+		'sort'              => $sort,
+		'display_comments'  => $display_comments,
+		'show_hidden'       => $show_hidden,
+		'in'                => $activity_ids,
+		'spam'              => $spam,
+		'update_meta_cache' => $update_meta_cache,
 	);
 	return apply_filters( 'bp_activity_get_specific', BP_Activity_Activity::get( $get_args ), $args, $get_args );
 }
 
 /**
- * Add an activity item
+ * Add an activity item.
  *
  * @since BuddyPress (1.1)
  *
- * @param array $args See docs for $defaults for details
- *
  * @uses wp_parse_args()
  * @uses BP_Activity_Activity::save() {@link BP_Activity_Activity}
  * @uses BP_Activity_Activity::rebuild_activity_comment_tree() {@link BP_Activity_Activity}
  * @uses wp_cache_delete()
  * @uses do_action() To call the 'bp_activity_add' hook
  *
- * @return int The activity id
+ * @param array $args {
+ *     An array of arguments.
+ *     @type int|bool $id Pass an activity ID to update an existing item, or
+ *           false to create a new item. Default: false.
+ *     @type string $action Optional. The activity action/description, typically
+ *           something like "Joe posted an update". Values passed to this param
+ *           will be stored in the database and used as a fallback for when the
+ *           activity item's format_callback cannot be found (eg, when the
+ *           component is disabled). As long as you have registered a
+ *           format_callback for your $type, it is unnecessary to include this
+ *           argument - BP will generate it automatically.
+ *           See {@link bp_activity_set_action()}.
+ *     @type string $content Optional. The content of the activity item.
+ *     @type string $component The unique name of the component associated with
+ *           the activity item - 'groups', 'profile', etc.
+ *     @type string $type The specific activity type, used for directory
+ *           filtering. 'new_blog_post', 'activity_update', etc.
+ *     @type string $primary_link Optional. The URL for this item, as used in
+ *           RSS feeds. Defaults to the URL for this activity item's permalink page.
+ *     @type int|bool $user_id Optional. The ID of the user associated with the
+ *           activity item. May be set to false or 0 if the item is not related
+ *           to any user. Default: the ID of the currently logged-in user.
+ *     @type int $item_id Optional. The ID of the associated item.
+ *     @type int $secondary_item_id Optional. The ID of a secondary associated
+ *           item.
+ *     @type string $date_recorded Optional. The GMT time, in Y-m-d h:i:s format,
+ *           when the item was recorded. Defaults to the current time.
+ *     @type bool $hide_sitewide Should the item be hidden on sitewide streams?
+ *           Default: false.
+ *     @type bool $is_spam Should the item be marked as spam? Default: false.
+ * }
+ * @return int|bool The ID of the activity on success. False on error.
  */
 function bp_activity_add( $args = '' ) {
 
@@ -1055,7 +1136,6 @@ function bp_activity_add( $args = '' ) {
 	$activity->user_id           = $user_id;
 	$activity->component         = $component;
 	$activity->type              = $type;
-	$activity->action            = $action;
 	$activity->content           = $content;
 	$activity->primary_link      = $primary_link;
 	$activity->item_id           = $item_id;
@@ -1063,6 +1143,7 @@ function bp_activity_add( $args = '' ) {
 	$activity->date_recorded     = $recorded_time;
 	$activity->hide_sitewide     = $hide_sitewide;
 	$activity->is_spam           = $is_spam;
+	$activity->action            = ! empty( $action ) ? $action : bp_activity_generate_action_string( $activity );
 
 	if ( !$activity->save() )
 		return false;
@@ -1078,24 +1159,26 @@ function bp_activity_add( $args = '' ) {
 }
 
 /**
- * Post an activity update
+ * Post an activity update.
  *
  * @since BuddyPress (1.2)
  *
- * @param array $args See docs for $defaults for details
- *
- * @global object $bp BuddyPress global settings
+ * @global object $bp BuddyPress global settings.
  * @uses wp_parse_args()
  * @uses bp_is_user_inactive()
  * @uses bp_core_get_userlink()
  * @uses bp_activity_add()
- * @uses apply_filters() To call the 'bp_activity_new_update_action' hook
- * @uses apply_filters() To call the 'bp_activity_new_update_content' hook
- * @uses apply_filters() To call the 'bp_activity_new_update_primary_link' hook
+ * @uses apply_filters() To call the 'bp_activity_new_update_action' hook.
+ * @uses apply_filters() To call the 'bp_activity_new_update_content' hook.
+ * @uses apply_filters() To call the 'bp_activity_new_update_primary_link' hook.
  * @uses bp_update_user_meta()
  * @uses wp_filter_kses()
- * @uses do_action() To call the 'bp_activity_posted_update' hook
+ * @uses do_action() To call the 'bp_activity_posted_update' hook.
  *
+ * @param array $args {
+ *     @type string $content The content of the activity update.
+ *     @type int $user_id Optional. Defaults to the logged-in user.
+ * }
  * @return int $activity_id The activity id
  */
 function bp_activity_post_update( $args = '' ) {
@@ -1116,18 +1199,16 @@ function bp_activity_post_update( $args = '' ) {
 
 	// Record this on the user's profile
 	$from_user_link   = bp_core_get_userlink( $user_id );
-	$activity_action  = sprintf( __( '%s posted an update', 'buddypress' ), $from_user_link );
 	$activity_content = $content;
 	$primary_link     = bp_core_get_userlink( $user_id, false, true );
 
 	// Now write the values
 	$activity_id = bp_activity_add( array(
 		'user_id'      => $user_id,
-		'action'       => apply_filters( 'bp_activity_new_update_action', $activity_action ),
 		'content'      => apply_filters( 'bp_activity_new_update_content', $activity_content ),
 		'primary_link' => apply_filters( 'bp_activity_new_update_primary_link', $primary_link ),
 		'component'    => $bp->activity->id,
-		'type'         => 'activity_update'
+		'type'         => 'activity_update',
 	) );
 
 	$activity_content = apply_filters( 'bp_activity_latest_update_content', $content, $activity_content );
@@ -1141,53 +1222,63 @@ function bp_activity_post_update( $args = '' ) {
 }
 
 /**
- * Add an activity comment
+ * Add an activity comment.
  *
  * @since BuddyPress (1.2)
  *
- * @param array $args See docs for $defaults for details
- *
- * @global object $bp BuddyPress global settings
+ * @global object $bp BuddyPress global settings.
  * @uses wp_parse_args()
  * @uses bp_activity_add()
- * @uses apply_filters() To call the 'bp_activity_comment_action' hook
- * @uses apply_filters() To call the 'bp_activity_comment_content' hook
+ * @uses apply_filters() To call the 'bp_activity_comment_action' hook.
+ * @uses apply_filters() To call the 'bp_activity_comment_content' hook.
  * @uses bp_activity_new_comment_notification()
  * @uses wp_cache_delete()
- * @uses do_action() To call the 'bp_activity_comment_posted' hook
- *
- * @return int $comment_id The comment id
+ * @uses do_action() To call the 'bp_activity_comment_posted' hook.
+ *
+ * @param array $args {
+ *     @type int $id Optional. Pass an ID to update an existing comment.
+ *     @type string $content The content of the comment.
+ *     @type int $user_id Optional. The ID of the user making the comment.
+ *                        Defaults to the ID of the logged-in user.
+ *     @type int $activity_id The ID of the "root" activity item, ie the oldest
+ *                            ancestor of the comment.
+ *     @type int $parent_id Optional. The ID of the parent activity item, ie the
+ *                          item to which the comment is an immediate reply. If
+ *                          not provided, this value defaults to the $activity_id.
+ * }
+ * @return int|bool The ID of the comment on success, otherwise false.
  */
 function bp_activity_new_comment( $args = '' ) {
-	global $bp;
 
-	$defaults = array(
+	$params = wp_parse_args( $args, array(
 		'id'          => false,
 		'content'     => false,
 		'user_id'     => bp_loggedin_user_id(),
 		'activity_id' => false, // ID of the root activity item
 		'parent_id'   => false  // ID of a parent comment (optional)
-	);
+	) );
 
-	$params = wp_parse_args( $args, $defaults );
 	extract( $params, EXTR_SKIP );
 
-	if ( empty( $content ) || empty( $user_id ) || empty( $activity_id ) )
+	// Bail if missing necessary data
+	if ( empty( $content ) || empty( $user_id ) || empty( $activity_id ) ) {
 		return false;
+	}
 
-	if ( empty( $parent_id ) )
+	// Maybe set current activity ID as the parent
+	if ( empty( $parent_id ) ) {
 		$parent_id = $activity_id;
+	}
 
 	// Check to see if the parent activity is hidden, and if so, hide this comment publically.
-	$activity = new BP_Activity_Activity( $activity_id );
+	$activity  = new BP_Activity_Activity( $activity_id );
 	$is_hidden = ( (int) $activity->hide_sitewide ) ? 1 : 0;
 
 	// Insert the activity comment
 	$comment_id = bp_activity_add( array(
 		'id'                => $id,
-		'action'            => apply_filters( 'bp_activity_comment_action', sprintf( __( '%s posted a new activity comment', 'buddypress' ), bp_core_get_userlink( $user_id ) ) ),
 		'content'           => apply_filters( 'bp_activity_comment_content', $content ),
-		'component'         => $bp->activity->id,
+		'component'         => buddypress()->activity->id,
 		'type'              => 'activity_comment',
 		'user_id'           => $user_id,
 		'item_id'           => $activity_id,
@@ -1195,13 +1286,19 @@ function bp_activity_new_comment( $args = '' ) {
 		'hide_sitewide'     => $is_hidden
 	) );
 
-	// Send an email notification if settings allow
-	bp_activity_new_comment_notification( $comment_id, $user_id, $params );
+	// Comment caches are stored only with the top-level item
+	wp_cache_delete( $activity_id, 'bp_activity_comments' );
 
-	// Clear the comment cache for this activity
-	wp_cache_delete( 'bp_activity_comments_' . $parent_id );
+	// Walk the tree to clear caches for all parent items
+	$clear_id = $parent_id;
+	while ( $clear_id != $activity_id ) {
+		$clear_object = new BP_Activity_Activity( $clear_id );
+		wp_cache_delete( $clear_id, 'bp_activity' );
+		$clear_id = intval( $clear_object->secondary_item_id );
+	}
+	wp_cache_delete( $activity_id, 'bp_activity' );
 
-	do_action( 'bp_activity_comment_posted', $comment_id, $params );
+	do_action( 'bp_activity_comment_posted', $comment_id, $params, $activity );
 
 	return $comment_id;
 }
@@ -1211,13 +1308,13 @@ function bp_activity_new_comment( $args = '' ) {
  *
  * @since BuddyPress (1.2)
  *
- * @param array $args See docs for $defaults for details
- *
+ * @see BP_Activity_Activity::get() For more information on accepted arguments.
  * @uses wp_parse_args()
- * @uses apply_filters() To call the 'bp_activity_get_activity_id' hook
+ * @uses apply_filters() To call the 'bp_activity_get_activity_id' hook.
  * @uses BP_Activity_Activity::save() {@link BP_Activity_Activity}
  *
- * @return int $activity_id The activity id
+ * @param array $args See BP_Activity_Activity::get() for description.
+ * @return int $activity_id The ID of the activity item found.
  */
 function bp_activity_get_activity_id( $args = '' ) {
 	$defaults = array(
@@ -1238,7 +1335,7 @@ function bp_activity_get_activity_id( $args = '' ) {
 }
 
 /**
- * Deleting Activity
+ * Delete activity item(s).
  *
  * If you're looking to hook into one action that provides the ID(s) of
  * the activity/activities deleted, then use:
@@ -1252,19 +1349,22 @@ function bp_activity_get_activity_id( $args = '' ) {
  *
  * @since BuddyPress (1.0)
  *
- * @param array $args See docs for $defaults for details
- *
+ * @see BP_Activity_Activity::get() For more information on accepted arguments.
  * @uses wp_parse_args()
  * @uses bp_activity_adjust_mention_count()
  * @uses BP_Activity_Activity::delete() {@link BP_Activity_Activity}
- * @uses do_action() To call the 'bp_before_activity_delete' hook
+ * @uses do_action() To call the 'bp_before_activity_delete' hook.
  * @uses bp_get_user_meta()
  * @uses bp_delete_user_meta()
- * @uses do_action() To call the 'bp_activity_delete' hook
- * @uses do_action() To call the 'bp_activity_deleted_activities' hook
+ * @uses do_action() To call the 'bp_activity_delete' hook.
+ * @uses do_action() To call the 'bp_activity_deleted_activities' hook.
  * @uses wp_cache_delete()
  *
- * @return bool True on success, false on failure
+ * @param array $args To delete specific activity items, use
+ *            $args = array( 'id' => $ids );
+ *        Otherwise, to use filters for item deletion, the argument format is
+ *        the same as BP_Activity_Activity::get(). See that method for a description.
+ * @return bool True on success, false on failure.
  */
 function bp_activity_delete( $args = '' ) {
 
@@ -1315,19 +1415,20 @@ function bp_activity_delete( $args = '' ) {
 }
 
 	/**
-	 * Delete an activity item by activity id
+	 * Delete an activity item by activity id.
 	 *
-	 * You should use bp_activity_delete() instead
+	 * You should use bp_activity_delete() instead.
 	 *
 	 * @since BuddyPress (1.1)
 	 * @deprecated BuddyPress (1.2)
 	 *
-	 * @param array $args See docs for $defaults for details
-	 *
 	 * @uses wp_parse_args()
 	 * @uses bp_activity_delete()
 	 *
-	 * @return bool True on success, false on failure
+	 * @param array $args See BP_Activity_Activity::get for a description
+	 *                    of accepted arguments.
+	 *
+	 * @return bool True on success, false on failure.
 	 */
 	function bp_activity_delete_by_item_id( $args = '' ) {
 
@@ -1345,77 +1446,75 @@ function bp_activity_delete( $args = '' ) {
 	}
 
 	/**
-	 * Delete an activity item by activity id
-	 *
-	 * You should use bp_activity_delete() instead
+	 * Delete an activity item by activity id.
 	 *
 	 * @since BuddyPress (1.1)
-	 * @deprecated BuddyPress (1.2)
-	 *
-	 * @param int $activity_id The activity id
 	 *
 	 * @uses bp_activity_delete()
 	 *
-	 * @return bool True on success, false on failure
+	 * @param int ID of the activity item to be deleted.
+	 * @return bool True on success, false on failure.
 	 */
 	function bp_activity_delete_by_activity_id( $activity_id ) {
 		return bp_activity_delete( array( 'id' => $activity_id ) );
 	}
 
 	/**
-	 * Delete an activity item by it's content
+	 * Delete an activity item by its content.
 	 *
-	 * You should use bp_activity_delete() instead
+	 * You should use bp_activity_delete() instead.
 	 *
 	 * @since BuddyPress (1.1)
 	 * @deprecated BuddyPress (1.2)
 	 *
-	 * @param int $user_id The user id
-	 * @param string $content The activity id
-	 * @param string $component The activity component
-	 * @param string $type The activity type
-	 *
 	 * @uses bp_activity_delete()
 	 *
-	 * @return bool True on success, false on failure
+	 * @param int $user_id The user id.
+	 * @param string $content The activity id.
+	 * @param string $component The activity component.
+	 * @param string $type The activity type.
+	 * @return bool True on success, false on failure.
 	 */
 	function bp_activity_delete_by_content( $user_id, $content, $component, $type ) {
 		return bp_activity_delete( array( 'user_id' => $user_id, 'content' => $content, 'component' => $component, 'type' => $type ) );
 	}
 
 	/**
-	 * Delete a user's activity for a component
+	 * Delete a user's activity for a component.
 	 *
-	 * You should use bp_activity_delete() instead
+	 * You should use bp_activity_delete() instead.
 	 *
 	 * @since BuddyPress (1.1)
 	 * @deprecated BuddyPress (1.2)
 	 *
-	 * @param int $user_id The user id
-	 * @param string $component The activity component
-	 *
 	 * @uses bp_activity_delete()
 	 *
-	 * @return bool True on success, false on failure
+	 * @param int $user_id The user id.
+	 * @param string $component The activity component.
+	 * @return bool True on success, false on failure.
 	 */
 	function bp_activity_delete_for_user_by_component( $user_id, $component ) {
 		return bp_activity_delete( array( 'user_id' => $user_id, 'component' => $component ) );
 	}
 
 /**
- * Delete an activity comment
+ * Delete an activity comment.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $activity_id The activity id
- * @param int $comment_id The activity comment id
- *
- * @uses apply_filters() To call the 'bp_activity_delete_comment_pre' hook
+ * @uses apply_filters() To call the 'bp_activity_delete_comment_pre' hook.
  * @uses bp_activity_delete_children()
  * @uses bp_activity_delete()
  * @uses BP_Activity_Activity::rebuild_activity_comment_tree() {@link BP_Activity_Activity}
- * @uses do_action() To call the 'bp_activity_delete_comment' hook
- *
+ * @uses do_action() To call the 'bp_activity_delete_comment' hook.
+ * @todo Why is an activity id required? We could look this up.
+ * @todo Why do we encourage users to call this function directly? We could just
+ *       as easily examine the activity type in bp_activity_delete() and then
+ *       call this function with the proper arguments if necessary.
+ *
+ * @param int $activity_id The ID of the "root" activity, ie the comment's
+ *                         oldest ancestor.
+ * @param int $comment_id The ID of the comment to be deleted.
  * @return bool True on success, false on failure
  */
 function bp_activity_delete_comment( $activity_id, $comment_id ) {
@@ -1442,16 +1541,17 @@ function bp_activity_delete_comment( $activity_id, $comment_id ) {
 }
 
 	/**
-	 * Delete an activity comment's children
+	 * Delete an activity comment's children.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @param int $activity_id The activity id
-	 * @param int $comment_id The activity comment id
-	 *
 	 * @uses BP_Activity_Activity::get_child_comments() {@link BP_Activity_Activity}
 	 * @uses bp_activity_delete_children()
 	 * @uses bp_activity_delete()
+	 *
+	 * @param int $activity_id The ID of the "root" activity, ie the
+	 *                         comment's oldest ancestor.
+	 * @param int $comment_id The ID of the comment to be deleted.
 	 */
 	function bp_activity_delete_children( $activity_id, $comment_id) {
 		// Recursively delete all children of this comment.
@@ -1464,22 +1564,22 @@ function bp_activity_delete_comment( $activity_id, $comment_id ) {
 	}
 
 /**
- * Get the permalink for a single activity item
+ * Get the permalink for a single activity item.
  *
- * When only the $activity_id param is passed, BP has to instantiate a new BP_Activity_Activity
- * object. To save yourself some processing overhead, be sure to pass the full $activity_obj param
- * as well, if you already have it available.
+ * When only the $activity_id param is passed, BP has to instantiate a new
+ * BP_Activity_Activity object. To save yourself some processing overhead,
+ * be sure to pass the full $activity_obj parameter as well, if you already
+ * have it available.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $activity_id The unique id of the activity object
- * @param object $activity_obj (optional) The activity object
- *
  * @uses bp_get_root_domain()
  * @uses bp_get_activity_root_slug()
- * @uses apply_filters_ref_array() To call the 'bp_activity_get_permalink' hook
+ * @uses apply_filters_ref_array() To call the 'bp_activity_get_permalink' hook.
  *
- * @return string $link Permalink for the activity item
+ * @param int $activity_id The unique id of the activity object.
+ * @param object $activity_obj Optional. The activity object.
+ * @return string $link Permalink for the activity item.
  */
 function bp_activity_get_permalink( $activity_id, $activity_obj = false ) {
 
@@ -1504,34 +1604,41 @@ function bp_activity_get_permalink( $activity_id, $activity_obj = false ) {
 }
 
 /**
- * Hide a user's activity
+ * Hide a user's activity.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $user_id The user id
- *
  * @uses BP_Activity_Activity::hide_all_for_user() {@link BP_Activity_Activity}
  *
- * @return bool True on success, false on failure
+ * @param int $user_id The ID of the user whose activity is being hidden.
+ * @return bool True on success, false on failure.
  */
 function bp_activity_hide_user_activity( $user_id ) {
 	return BP_Activity_Activity::hide_all_for_user( $user_id );
 }
 
 /**
- * Take content, remove all images and replace them with one thumbnail image.
+ * Take content, remove images, and replace them with a single thumbnail image.
  *
- * @since BuddyPress (1.2)
+ * The format of items in the activity stream is such that we do not want to
+ * allow an arbitrary number of arbitrarily large images to be rendered.
+ * However, the activity stream is built to elegantly display a single
+ * thumbnail corresponding to the activity comment. This function looks
+ * through the content, grabs the first image and converts it to a thumbnail,
+ * and removes the rest of the images from the string.
  *
- * @param string $content The content to work with
- * @param string $link Optional. The URL that the image should link to
- * @param array $activity_args Optional. The args passed to the activity
- *   creation function (eg bp_blogs_record_activity())
+ * @since BuddyPress (1.2)
  *
  * @uses esc_attr()
  * @uses apply_filters() To call the 'bp_activity_thumbnail_content_images' hook
  *
- * @return string $content The content with images stripped and replaced with a single thumb.
+ * @param string $content The content of the activity item.
+ * @param string $link Optional. The unescaped URL that the image should link
+ *                               to. If absent, the image will not be a link.
+ * @param array $activity_args Optional. The args passed to the activity
+ *                             creation function (eg bp_blogs_record_activity()).
+ * @return string $content The content with images stripped and replaced with a
+ *                         single thumb.
  */
 function bp_activity_thumbnail_content_images( $content, $link = false, $args = false ) {
 
@@ -1561,11 +1668,10 @@ function bp_activity_thumbnail_content_images( $content, $link = false, $args =
 			$ratio      = (int) $width / (int) $height;
 			$new_height = (int) $height >= 100 ? 100 : $height;
 			$new_width  = $new_height * $ratio;
-
-			$image = '<img src="' . esc_attr( $src ) . '" width="' . $new_width . '" height="' . $new_height . '" alt="' . __( 'Thumbnail', 'buddypress' ) . '" class="align-left thumbnail" />';
+			$image      = '<img src="' . esc_url( $src ) . '" width="' . absint( $new_width ) . '" height="' . absint( $new_height ) . '" alt="' . __( 'Thumbnail', 'buddypress' ) . '" class="align-left thumbnail" />';
 
 			if ( !empty( $link ) ) {
-				$image = '<a href="' . $link . '">' . $image . '</a>';
+				$image = '<a href="' . esc_url( $link ) . '">' . $image . '</a>';
 			}
 
 			$content = $image . $content;
@@ -1576,23 +1682,27 @@ function bp_activity_thumbnail_content_images( $content, $link = false, $args =
 }
 
 /**
- * Convenience function to control whether the current user is allowed to mark activity items as spam
+ * Fetch whether the current user is allowed to mark items as spam.
  *
- * @return bool True if user is allowed to mark activity items as spam
  * @since BuddyPress (1.6)
- * @static
+ *
+ * @return bool True if user is allowed to mark activity items as spam.
  */
 function bp_activity_user_can_mark_spam() {
 	return apply_filters( 'bp_activity_user_can_mark_spam', bp_current_user_can( 'bp_moderate' ) );
 }
 
 /**
- * Mark activity item as spam
+ * Mark an activity item as spam.
  *
- * @global object $bp BuddyPress global settings
- * @param BP_Activity_Activity $activity
- * @param string $source Optional; default is "by_a_person" (e.g. a person has manually marked the activity as spam).
  * @since BuddyPress (1.6)
+ *
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param BP_Activity_Activity $activity The activity item to be spammed.
+ * @param string $source Optional. Default is "by_a_person" (ie, a person has
+ *                       manually marked the activity as spam). BP core also
+ *                       accepts 'by_akismet'.
  */
 function bp_activity_mark_as_spam( &$activity, $source = 'by_a_person' ) {
 	global $bp;
@@ -1603,7 +1713,7 @@ function bp_activity_mark_as_spam( &$activity, $source = 'by_a_person' ) {
 	wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
 
 	// Clear the activity comment cache for this activity item
-	wp_cache_delete( 'bp_activity_comments_' . $activity->id, 'bp' );
+	wp_cache_delete( $activity->id, 'bp_activity_comments' );
 
 	// If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity
 	if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
@@ -1623,12 +1733,16 @@ function bp_activity_mark_as_spam( &$activity, $source = 'by_a_person' ) {
 }
 
 /**
- * Mark activity item as ham
+ * Mark an activity item as ham.
  *
- * @global object $bp BuddyPress global settings
- * @param BP_Activity_Activity $activity
- * @param string $source Optional; default is "by_a_person" (e.g. a person has manually marked the activity as spam).
  * @since BuddyPress (1.6)
+ *
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param BP_Activity_Activity $activity The activity item to be hammed.
+ * @param string $source Optional. Default is "by_a_person" (ie, a person has
+ *                       manually marked the activity as spam). BP core also
+ *                       accepts 'by_akismet'.
  */
 function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
 	global $bp;
@@ -1639,7 +1753,7 @@ function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
 	wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
 
 	// Clear the activity comment cache for this activity item
-	wp_cache_delete( 'bp_activity_comments_' . $activity->id, 'bp' );
+	wp_cache_delete( $activity->id, 'bp_activity_comments' );
 
 	// If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity
 	if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
@@ -1662,8 +1776,11 @@ function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
 /** Embeds *******************************************************************/
 
 /**
- * Grabs the activity update ID and attempts to retrieve the oEmbed cache (if it exists)
- * during the activity loop.  If no cache and link is embeddable, cache it.
+ * Set up activity oEmbed cache during the activity loop.
+ *
+ * During an activity loop, this function sets up the hooks necessary to grab
+ * each item's embeds from the cache, or put them in the cache if they are
+ * not there yet.
  *
  * This does not cover recursive activity comments, as they do not use a real loop.
  * For that, see {@link bp_activity_comment_embed()}.
@@ -1673,10 +1790,9 @@ function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
  * @see BP_Embed
  * @see bp_embed_activity_cache()
  * @see bp_embed_activity_save_cache()
- *
- * @uses add_filter() To attach 'bp_get_activity_id' to 'embed_post_id'
- * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'
- * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'
+ * @uses add_filter() To attach 'bp_get_activity_id' to 'embed_post_id'.
+ * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'.
+ * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'.
  */
 function bp_activity_embed() {
 	add_filter( 'embed_post_id',         'bp_get_activity_id'                  );
@@ -1686,19 +1802,21 @@ function bp_activity_embed() {
 add_action( 'activity_loop_start', 'bp_activity_embed' );
 
 /**
- * Grabs the activity comment ID and attempts to retrieve the oEmbed cache (if it exists)
- * when BP is recursing through activity comments {@link bp_activity_recurse_comments()}.
- * If no cache and link is embeddable, cache it.
+ * Set up activity oEmbed cache while recursing through activity comments.
+ *
+ * While crawling through an activity comment tree
+ * ({@link bp_activity_recurse_comments}), this function sets up the hooks
+ * necessary to grab each comment's embeds from the cache, or put them in
+ * the cache if they are not there yet.
  *
  * @since BuddyPress (1.5)
  *
  * @see BP_Embed
  * @see bp_embed_activity_cache()
  * @see bp_embed_activity_save_cache()
- *
- * @uses add_filter() To attach 'bp_get_activity_comment_id' to 'embed_post_id'
- * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'
- * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'
+ * @uses add_filter() To attach 'bp_get_activity_comment_id' to 'embed_post_id'.
+ * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'.
+ * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'.
  */
 function bp_activity_comment_embed() {
 	add_filter( 'embed_post_id',         'bp_get_activity_comment_id'          );
@@ -1713,13 +1831,12 @@ add_action( 'bp_before_activity_comment', 'bp_activity_comment_embed' );
  * @since BuddyPress (1.5)
  *
  * @see BP_Embed
- *
- * @param object $activity The activity that is being expanded
- *
  * @global object $bp BuddyPress global settings
- * @uses add_filter() To attach create_function() to 'embed_post_id'
- * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'
- * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'
+ * @uses add_filter() To attach create_function() to 'embed_post_id'.
+ * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'.
+ * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'.
+ *
+ * @param object $activity The activity that is being expanded.
  */
 function bp_dtheme_embed_read_more( $activity ) {
 	global $bp;
@@ -1733,15 +1850,15 @@ function bp_dtheme_embed_read_more( $activity ) {
 add_action( 'bp_dtheme_get_single_activity_content', 'bp_dtheme_embed_read_more' );
 
 /**
- * Removes the 'embed_post_id' filter after {@link bp_activity_recurse_comments()}
- * is rendered to avoid conflict with the 'embed_post_id' filter in
- * {@link bp_activity_embed()} or any other component embeds.
+ * Clean up 'embed_post_id' filter after comment recursion.
+ *
+ * This filter must be removed so that the non-comment filters take over again
+ * once the comments are done being processed.
  *
  * @since BuddyPress (1.5)
  *
  * @see bp_activity_comment_embed()
- *
- * @uses remove_filter() To remove 'bp_get_activity_comment_id' from 'embed_post_id'
+ * @uses remove_filter() To remove 'bp_get_activity_comment_id' from 'embed_post_id'.
  */
 function bp_activity_comment_embed_after_recurse() {
 	remove_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
@@ -1749,27 +1866,80 @@ function bp_activity_comment_embed_after_recurse() {
 add_action( 'bp_after_activity_comment', 'bp_activity_comment_embed_after_recurse' );
 
 /**
- * Wrapper function for {@link bp_activity_get_meta()}.
+ * Fetch an activity item's cached embeds.
+ *
  * Used during {@link BP_Embed::parse_oembed()} via {@link bp_activity_embed()}.
  *
  * @since BuddyPress (1.5)
  *
+ * @see BP_Embed::parse_oembed()
  * @uses bp_activity_get_meta()
  *
- * @return mixed The activity meta
+ * @param string $cache An empty string passed by BP_Embed::parse_oembed() for
+ *                      functions like this one to filter.
+ * @param int $id The ID of the activity item.
+ * @param string $cachekey The cache key generated in BP_Embed::parse_oembed().
+ * @return mixed The cached embeds for this activity item.
  */
 function bp_embed_activity_cache( $cache, $id, $cachekey ) {
 	return bp_activity_get_meta( $id, $cachekey );
 }
 
 /**
- * Wrapper function for {@link bp_activity_update_meta()}.
+ * Set an activity item's embed cache.
+ *
  * Used during {@link BP_Embed::parse_oembed()} via {@link bp_activity_embed()}.
  *
  * @since BuddyPress (1.5)
  *
+ * @see BP_Embed::parse_oembed()
  * @uses bp_activity_update_meta()
+ *
+ * @param string $cache An empty string passed by BP_Embed::parse_oembed() for
+ *                      functions like this one to filter.
+ * @param int $id The ID of the activity item.
+ * @param string $cachekey The cache key generated in BP_Embed::parse_oembed().
+ * @return bool True on success, false on failure.
  */
 function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
 	bp_activity_update_meta( $id, $cachekey, $cache );
 }
+
+/**
+ * Should we use Heartbeat to refresh activities?
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @uses bp_is_activity_heartbeat_active() to check if heatbeat setting is on.
+ * @uses bp_is_activity_directory() to check if the current page is the activity
+ *       directory.
+ * @uses bp_is_active() to check if the group component is active.
+ * @uses bp_is_group_activity() to check if on a single group, the current page
+ *       is the group activities.
+ * @uses bp_is_group_home() to check if the current page is a single group home
+ *       page.
+ *
+ * @return bool True if activity heartbeat is enabled, otherwise false.
+ */
+function bp_activity_do_heartbeat() {
+	$retval = false;
+
+	if ( ! bp_is_activity_heartbeat_active() ) {
+		return $retval;
+	}
+
+	if ( bp_is_activity_directory() ) {
+		$retval = true;
+	}
+
+	if ( bp_is_active( 'groups') ) {
+		// If no custom front, then activities are loaded in group's home
+		$has_custom_front = bp_locate_template( array( 'groups/single/front.php' ), false, true );
+
+		if ( bp_is_group_activity() || ( ! $has_custom_front && bp_is_group_home() ) ) {
+			$retval = true;
+		}
+	}
+
+	return $retval;
+}
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-loader.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-loader.php
index 9a0074f5976a4c88ed2da0fa42cc975eb05149f0..0f68f91398e6c0270f40b3444f4be3b636202561 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-loader.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-loader.php
@@ -1,9 +1,9 @@
 <?php
 
 /**
- * BuddyPress Activity Streams Loader
+ * BuddyPress Activity Streams Loader.
  *
- * An activity stream component, for users, groups, and blog tracking.
+ * An activity stream component, for users, groups, and site tracking.
  *
  * @package BuddyPress
  * @subpackage ActivityCore
@@ -13,29 +13,36 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Main Activity Class
+ * Main Activity Class.
  *
  * @since BuddyPress (1.5)
  */
 class BP_Activity_Component extends BP_Component {
 
 	/**
-	 * Start the activity component creation process
+	 * Start the activity component setup process.
 	 *
 	 * @since BuddyPress (1.5)
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'activity',
 			__( 'Activity Streams', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 10
+			)
 		);
 	}
 
 	/**
-	 * Include files
+	 * Include component files.
 	 *
 	 * @since BuddyPress (1.5)
+	 *
+	 * @see BP_Component::includes() for a description of arguments.
+	 *
+	 * @param array $includes See BP_Component::includes() for a description.
 	 */
 	public function includes( $includes = array() ) {
 		// Files to include
@@ -52,27 +59,31 @@ class BP_Activity_Component extends BP_Component {
 
 		// Load Akismet support if Akismet is configured
 		$akismet_key = bp_get_option( 'wordpress_api_key' );
-		if ( defined( 'AKISMET_VERSION' ) && ( !empty( $akismet_key ) || defined( 'WPCOM_API_KEY' ) ) && apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) )
+		if ( defined( 'AKISMET_VERSION' ) && ( !empty( $akismet_key ) || defined( 'WPCOM_API_KEY' ) ) && apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) ) {
 			$includes[] = 'akismet';
+		}
 
-		if ( is_admin() )
+		if ( is_admin() ) {
 			$includes[] = 'admin';
+		}
 
 		parent::includes( $includes );
 	}
 
 	/**
-	 * Setup globals
+	 * Set up component global variables.
 	 *
 	 * The BP_ACTIVITY_SLUG constant is deprecated, and only used here for
 	 * backwards compatibility.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
-	 * @global object $bp BuddyPress global settings
+	 * @see BP_Component::setup_globals() for a description of arguments.
+	 *
+	 * @param array $args See BP_Component::setup_globals() for a description.
 	 */
 	public function setup_globals( $args = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		// Define a slug, if necessary
 		if ( !defined( 'BP_ACTIVITY_SLUG' ) )
@@ -84,35 +95,45 @@ class BP_Activity_Component extends BP_Component {
 			'table_name_meta' => $bp->table_prefix . 'bp_activity_meta',
 		);
 
+		// Metadata tables for groups component
+		$meta_tables = array(
+			'activity' => $bp->table_prefix . 'bp_activity_meta',
+		);
+
 		// All globals for activity component.
 		// Note that global_tables is included in this array.
-		$globals = array(
+		$args = array(
 			'slug'                  => BP_ACTIVITY_SLUG,
 			'root_slug'             => isset( $bp->pages->activity->slug ) ? $bp->pages->activity->slug : BP_ACTIVITY_SLUG,
 			'has_directory'         => true,
+			'directory_title'       => _x( 'Sitewide Activity', 'component directory title', 'buddypress' ),
+			'notification_callback' => 'bp_activity_format_notifications',
 			'search_string'         => __( 'Search Activity...', 'buddypress' ),
 			'global_tables'         => $global_tables,
-			'notification_callback' => 'bp_activity_format_notifications',
+			'meta_tables'           => $meta_tables,
 		);
 
-		parent::setup_globals( $globals );
+		parent::setup_globals( $args );
 	}
 
 	/**
-	 * Setup BuddyBar navigation
+	 * Set up component navigation.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
-	 * @global object $bp BuddyPress global settings
+	 * @see BP_Component::setup_nav() for a description of arguments.
 	 * @uses bp_is_active()
 	 * @uses is_user_logged_in()
 	 * @uses bp_get_friends_slug()
 	 * @uses bp_get_groups_slug()
+	 *
+	 * @param array $main_nav Optional. See BP_Component::setup_nav() for
+	 *                        description.
+	 * @param array $sub_nav Optional. See BP_Component::setup_nav() for
+	 *                       description.
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
 
-		$sub_nav = array();
-
 		// Add 'Activity' to the main navigation
 		$main_nav = array(
 			'name'                => __( 'Activity', 'buddypress' ),
@@ -203,11 +224,12 @@ class BP_Activity_Component extends BP_Component {
 	}
 
 	/**
-	 * Set up the Toolbar
+	 * Set up the component entries in the WordPress Admin Bar.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
-	 * @global object $bp BuddyPress global settings
+	 * @see BP_Component::setup_nav() for a description of the $wp_admin_nav
+	 *      parameter array.
 	 * @uses is_user_logged_in()
 	 * @uses trailingslashit()
 	 * @uses bp_get_total_mention_count_for_user()
@@ -215,12 +237,12 @@ class BP_Activity_Component extends BP_Component {
 	 * @uses bp_is_active()
 	 * @uses bp_get_friends_slug()
 	 * @uses bp_get_groups_slug()
+	 *
+	 * @param array $wp_admin_nav See BP_Component::setup_admin_bar() for a
+	 *                            description.
 	 */
 	public function setup_admin_bar( $wp_admin_nav = array() ) {
-		global $bp;
-
-		// Prevent debug notices
-		$wp_admin_nav = array();
+		$bp = buddypress();
 
 		// Menus for logged in user
 		if ( is_user_logged_in() ) {
@@ -247,6 +269,14 @@ class BP_Activity_Component extends BP_Component {
 				'href'   => trailingslashit( $activity_link )
 			);
 
+			// Personal
+			$wp_admin_nav[] = array(
+				'parent' => 'my-account-' . $this->id,
+				'id'     => 'my-account-' . $this->id . '-personal',
+				'title'  => __( 'Personal', 'buddypress' ),
+				'href'   => trailingslashit( $activity_link )
+			);
+
 			// Mentions
 			if ( bp_activity_do_mentions() ) {
 				$wp_admin_nav[] = array(
@@ -257,14 +287,6 @@ class BP_Activity_Component extends BP_Component {
 				);
 			}
 
-			// Personal
-			$wp_admin_nav[] = array(
-				'parent' => 'my-account-' . $this->id,
-				'id'     => 'my-account-' . $this->id . '-personal',
-				'title'  => __( 'Personal', 'buddypress' ),
-				'href'   => trailingslashit( $activity_link )
-			);
-
 			// Favorites
 			$wp_admin_nav[] = array(
 				'parent' => 'my-account-' . $this->id,
@@ -298,17 +320,16 @@ class BP_Activity_Component extends BP_Component {
 	}
 
 	/**
-	 * Sets up the title for pages and <title>
+	 * Set up the title for pages and <title>.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
-	 * @global object $bp BuddyPress global settings
 	 * @uses bp_is_activity_component()
 	 * @uses bp_is_my_profile()
 	 * @uses bp_core_fetch_avatar()
 	 */
-	function setup_title() {
-		global $bp;
+	public function setup_title() {
+		$bp = buddypress();
 
 		// Adjust title based on view
 		if ( bp_is_activity_component() ) {
@@ -328,11 +349,11 @@ class BP_Activity_Component extends BP_Component {
 	}
 
 	/**
-	 * Setup the actions
+	 * Set up actions necessary for the component.
 	 *
 	 * @since BuddyPress (1.6)
 	 */
-	 function setup_actions() {
+	public function setup_actions() {
 		// Spam prevention
 		add_action( 'bp_include', 'bp_activity_setup_akismet' );
 
@@ -340,9 +361,10 @@ class BP_Activity_Component extends BP_Component {
 	}
 }
 
+/**
+ * Bootstrap the Activity component.
+ */
 function bp_setup_activity() {
-	global $bp;
-
-	$bp->activity = new BP_Activity_Component();
+	buddypress()->activity = new BP_Activity_Component();
 }
 add_action( 'bp_setup_components', 'bp_setup_activity', 6 );
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-notifications.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-notifications.php
index fd437a764d9e8a40623cf81dc7ef54b670f0ef0c..005b4c759dc9b1a476691e9e8717aff4a50a9dc5 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-notifications.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-notifications.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Activity Notifications
+ * BuddyPress Activity Notifications.
  *
  * @package BuddyPress
  * @subpackage ActivityNotifications
@@ -10,15 +10,14 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/* Emails *********************************************************************/
+
 /**
- * Sends an email notification and a BP notification when someone mentions you in an update
+ * Send email and BP notifications when a user is mentioned in an update.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $activity_id The id of the activity update
- * @param int $receiver_user_id The unique user_id of the user who is receiving the update
- *
- * @uses bp_core_add_notification()
+ * @uses bp_notifications_add_notification()
  * @uses bp_get_user_meta()
  * @uses bp_core_get_user_displayname()
  * @uses bp_activity_get_permalink()
@@ -31,11 +30,14 @@ if ( !defined( 'ABSPATH' ) ) exit;
  * @uses bp_is_active()
  * @uses bp_is_group()
  * @uses bp_get_current_group_name()
- * @uses apply_filters() To call the 'bp_activity_at_message_notification_to' hook
- * @uses apply_filters() To call the 'bp_activity_at_message_notification_subject' hook
- * @uses apply_filters() To call the 'bp_activity_at_message_notification_message' hook
+ * @uses apply_filters() To call the 'bp_activity_at_message_notification_to' hook.
+ * @uses apply_filters() To call the 'bp_activity_at_message_notification_subject' hook.
+ * @uses apply_filters() To call the 'bp_activity_at_message_notification_message' hook.
  * @uses wp_mail()
  * @uses do_action() To call the 'bp_activity_sent_mention_email' hook
+ *
+ * @param int $activity_id The ID of the activity update.
+ * @param int $receiver_user_id The ID of the user who is receiving the update.
  */
 function bp_activity_at_message_notification( $activity_id, $receiver_user_id ) {
 
@@ -54,9 +56,6 @@ function bp_activity_at_message_notification( $activity_id, $receiver_user_id )
 	$message = '';
 	$content = '';
 
-	// Add the BP notification
-	bp_core_add_notification( $activity_id, $receiver_user_id, 'activity', 'new_at_mention', $activity->user_id );
-
 	// Now email the user with the contents of the message (if they have enabled email notifications)
 	if ( 'no' != bp_get_user_meta( $receiver_user_id, 'notification_activity_new_mention', true ) ) {
 		$poster_name = bp_core_get_user_displayname( $activity->user_id );
@@ -100,7 +99,7 @@ To view and respond to the message, log in and visit: %3$s
 			$message .= sprintf( __( 'To disable these notifications please log in and go to: %s', 'buddypress' ), $settings_link );
 		}
 
-		/* Send the message */
+		// Send the message
 		$to 	 = apply_filters( 'bp_activity_at_message_notification_to', $to );
 		$subject = apply_filters( 'bp_activity_at_message_notification_subject', $subject, $poster_name );
 		$message = apply_filters( 'bp_activity_at_message_notification_message', $message, $poster_name, $content, $message_link, $settings_link );
@@ -108,18 +107,14 @@ To view and respond to the message, log in and visit: %3$s
 		wp_mail( $to, $subject, $message );
 	}
 
-	do_action( 'bp_activity_sent_mention_email', $activity, $subject, $message, $content );
+	do_action( 'bp_activity_sent_mention_email', $activity, $subject, $message, $content, $receiver_user_id );
 }
 
 /**
- * Sends an email notification and a BP notification when someone mentions you in an update
+ * Send email and BP notifications when an activity item receives a comment.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $comment_id The comment id
- * @param int $commenter_id The unique user_id of the user who posted the comment
- * @param array $params {@link bp_activity_new_comment()}
- *
  * @uses bp_get_user_meta()
  * @uses bp_core_get_user_displayname()
  * @uses bp_activity_get_permalink()
@@ -139,8 +134,12 @@ To view and respond to the message, log in and visit: %3$s
  * @uses apply_filters() To call the 'bp_activity_new_comment_notification_comment_author_subject' hook
  * @uses apply_filters() To call the 'bp_activity_new_comment_notification_comment_author_message' hook
  * @uses do_action() To call the 'bp_activity_sent_reply_to_reply_email' hook
+ *
+ * @param int $comment_id The comment id.
+ * @param int $commenter_id The ID of the user who posted the comment.
+ * @param array $params {@link bp_activity_new_comment()}
  */
-function bp_activity_new_comment_notification( $comment_id, $commenter_id, $params ) {
+function bp_activity_new_comment_notification( $comment_id = 0, $commenter_id = 0, $params = array() ) {
 
 	// Set some default parameters
 	$activity_id = 0;
@@ -192,8 +191,9 @@ To view your original update and all comments, log in and visit: %3$s
 	 * If this is a reply to another comment, send an email notification to the
 	 * author of the immediate parent comment.
 	 */
-	if ( empty( $parent_id ) || ( $activity_id == $parent_id ) )
+	if ( empty( $parent_id ) || ( $activity_id == $parent_id ) ) {
 		return false;
+	}
 
 	$parent_comment = new BP_Activity_Activity( $parent_id );
 
@@ -236,3 +236,160 @@ To view the original activity, your comment and all replies, log in and visit: %
 		do_action( 'bp_activity_sent_reply_to_reply_email', $original_activity->user_id, $subject, $message, $comment_id, $commenter_id, $params );
 	}
 }
+
+/**
+ * Helper method to map action arguments to function parameters
+ *
+ * @since BuddyPress (1.9.0)
+ * @param int $comment_id
+ * @param array $params
+ */
+function bp_activity_new_comment_notification_helper( $comment_id, $params ) {
+	bp_activity_new_comment_notification( $comment_id, $params['user_id'], $params );
+}
+add_action( 'bp_activity_comment_posted', 'bp_activity_new_comment_notification_helper', 10, 2 );
+
+/** Notifications *************************************************************/
+
+/**
+ * Format notifications related to activity.
+ *
+ * @since BuddyPress (1.5)
+ *
+ * @uses bp_loggedin_user_domain()
+ * @uses bp_get_activity_slug()
+ * @uses bp_core_get_user_displayname()
+ * @uses apply_filters() To call the 'bp_activity_multiple_at_mentions_notification' hook.
+ * @uses apply_filters() To call the 'bp_activity_single_at_mentions_notification' hook.
+ * @uses do_action() To call 'activity_format_notifications' hook.
+ *
+ * @param string $action The type of activity item. Just 'new_at_mention' for now.
+ * @param int $item_id The activity ID.
+ * @param int $secondary_item_id In the case of at-mentions, this is the mentioner's ID.
+ * @param int $total_items The total number of notifications to format.
+ * @param string $format 'string' to get a BuddyBar-compatible notification, 'array' otherwise.
+ * @return string $return Formatted @mention notification.
+ */
+function bp_activity_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
+
+	switch ( $action ) {
+		case 'new_at_mention':
+			$activity_id      = $item_id;
+			$poster_user_id   = $secondary_item_id;
+			$at_mention_link  = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/';
+			$at_mention_title = sprintf( __( '@%s Mentions', 'buddypress' ), bp_get_loggedin_user_username() );
+
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( 'You have %1$d new mentions', 'buddypress' ), (int) $total_items );
+				$filter = 'bp_activity_multiple_at_mentions_notification';
+			} else {
+				$user_fullname = bp_core_get_user_displayname( $poster_user_id );
+				$text =  sprintf( __( '%1$s mentioned you', 'buddypress' ), $user_fullname );
+				$filter = 'bp_activity_single_at_mentions_notification';
+			}
+		break;
+	}
+
+	if ( 'string' == $format ) {
+		$return = apply_filters( $filter, '<a href="' . esc_url( $at_mention_link ) . '" title="' . esc_attr( $at_mention_title ) . '">' . esc_html( $text ) . '</a>', $at_mention_link, (int) $total_items, $activity_id, $poster_user_id );
+	} else {
+		$return = apply_filters( $filter, array(
+			'text' => $text,
+			'link' => $at_mention_link
+		), $at_mention_link, (int) $total_items, $activity_id, $poster_user_id );
+	}
+
+	do_action( 'activity_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
+
+	return $return;
+}
+
+/**
+ * Notify a member when their nicename is mentioned in an activity stream item.
+ *
+ * Hooked to the 'bp_activity_sent_mention_email' action, we piggy back off the
+ * existing email code for now, since it does the heavy lifting for us. In the
+ * future when we separate emails from Notifications, this will need its own
+ * 'bp_activity_at_name_send_emails' equivalent helper function.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param obj $activity
+ * @param string $subject (not used)
+ * @param string $message (not used)
+ * @param string $content (not used)
+ * @param int $receiver_user_id
+ */
+function bp_activity_at_mention_add_notification( $activity, $subject, $message, $content, $receiver_user_id ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_add_notification( array(
+			'user_id'           => $receiver_user_id,
+			'item_id'           => $activity->id,
+			'secondary_item_id' => $activity->user_id,
+			'component_name'    => buddypress()->activity->id,
+			'component_action'  => 'new_at_mention',
+			'date_notified'     => bp_core_current_time(),
+			'is_new'            => 1,
+		) );
+	}
+}
+add_action( 'bp_activity_sent_mention_email', 'bp_activity_at_mention_add_notification', 10, 5 );
+
+/**
+ * Mark at-mention notifications as read when users visit their Mentions page.
+ *
+ * @since BuddyPress (1.5)
+ *
+ * @uses bp_notifications_mark_all_notifications_by_type()
+ */
+function bp_activity_remove_screen_notifications() {
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return;
+	}
+
+	// Only mark read if you're looking at your own mentions
+	if ( ! bp_is_my_profile() ) {
+		return;
+	}
+
+	bp_notifications_mark_notifications_by_type( bp_loggedin_user_id(), buddypress()->activity->id, 'new_at_mention' );
+}
+add_action( 'bp_activity_screen_mentions', 'bp_activity_remove_screen_notifications' );
+
+/**
+ * Mark at-mention notification as read when user visits the activity with the mention.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_activity_remove_screen_notifications_single_activity_permalink( $activity ) {
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return;
+	}
+
+	if ( ! is_user_logged_in() ) {
+		return;
+	}
+
+	// Mark as read any notifications for the current user related to this
+	// activity item
+	bp_notifications_mark_notifications_by_item_id( bp_loggedin_user_id(), $activity->id, buddypress()->activity->id, 'new_at_mention' );
+}
+add_action( 'bp_activity_screen_single_activity_permalink', 'bp_activity_remove_screen_notifications_single_activity_permalink' );
+
+/**
+ * Delete at-mention notifications when the corresponding activity item is deleted.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $activity_ids_deleted IDs of deleted activity items.
+ */
+function bp_activity_at_mention_delete_notification( $activity_ids_deleted = array() ) {
+	// Let's delete all without checking if content contains any mentions
+	// to avoid a query to get the activity
+	if ( bp_is_active( 'notifications' ) && ! empty( $activity_ids_deleted ) ) {
+		foreach ( $activity_ids_deleted as $activity_id ) {
+			bp_notifications_delete_all_notifications_by_type( $activity_id, buddypress()->activity->id );
+		}
+	}
+}
+add_action( 'bp_activity_deleted_activities', 'bp_activity_at_mention_delete_notification', 10 );
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-screens.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-screens.php
index eddf90697503b22338f681414e3d6b395eb8f6d2..24067712fc23c45f5be0e41147ccbd366c623eac 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-screens.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-screens.php
@@ -1,7 +1,11 @@
 <?php
 
 /**
- * BuddyPress Activity Screens
+ * BuddyPress Activity Screens.
+ *
+ * The functions in this file detect, with each page load, whether an Activity
+ * component page is being requested. If so, it parses any necessary data from
+ * the URL, and tells BuddyPress to load the appropriate template.
  *
  * @package BuddyPress
  * @subpackage ActivityScreens
@@ -11,7 +15,7 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Activity screen index
+ * Load the Activity directory.
  *
  * @since BuddyPress (1.5)
  *
@@ -19,12 +23,12 @@ if ( !defined( 'ABSPATH' ) ) exit;
  * @uses bp_is_activity_component()
  * @uses bp_current_action()
  * @uses bp_update_is_directory()
- * @uses do_action() To call the 'bp_activity_screen_index' hook
+ * @uses do_action() To call the 'bp_activity_screen_index' hook.
  * @uses bp_core_load_template()
- * @uses apply_filters() To call the 'bp_activity_screen_index' hook
+ * @uses apply_filters() To call the 'bp_activity_screen_index' hook.
  */
 function bp_activity_screen_index() {
-	if ( !bp_displayed_user_id() && bp_is_activity_component() && !bp_current_action() ) {
+	if ( bp_is_activity_directory() ) {
 		bp_update_is_directory( true, 'activity' );
 
 		do_action( 'bp_activity_screen_index' );
@@ -35,13 +39,13 @@ function bp_activity_screen_index() {
 add_action( 'bp_screens', 'bp_activity_screen_index' );
 
 /**
- * Activity screen 'my activity' index
+ * Load the 'My Activity' page.
  *
  * @since BuddyPress (1.0)
  *
- * @uses do_action() To call the 'bp_activity_screen_my_activity' hook
+ * @uses do_action() To call the 'bp_activity_screen_my_activity' hook.
  * @uses bp_core_load_template()
- * @uses apply_filters() To call the 'bp_activity_template_my_activity' hook
+ * @uses apply_filters() To call the 'bp_activity_template_my_activity' hook.
  */
 function bp_activity_screen_my_activity() {
 	do_action( 'bp_activity_screen_my_activity' );
@@ -49,16 +53,16 @@ function bp_activity_screen_my_activity() {
 }
 
 /**
- * Activity screen 'friends' index
+ * Load the 'My Friends' activity page.
  *
  * @since BuddyPress (1.0)
  *
  * @uses bp_is_active()
  * @uses bp_update_is_item_admin()
  * @uses bp_current_user_can()
- * @uses do_action() To call the 'bp_activity_screen_friends' hook
+ * @uses do_action() To call the 'bp_activity_screen_friends' hook.
  * @uses bp_core_load_template()
- * @uses apply_filters() To call the 'bp_activity_template_friends_activity' hook
+ * @uses apply_filters() To call the 'bp_activity_template_friends_activity' hook.
  */
 function bp_activity_screen_friends() {
 	if ( !bp_is_active( 'friends' ) )
@@ -70,7 +74,7 @@ function bp_activity_screen_friends() {
 }
 
 /**
- * Activity screen 'groups' index
+ * Load the 'My Groups' activity page.
  *
  * @since BuddyPress (1.2)
  *
@@ -91,7 +95,7 @@ function bp_activity_screen_groups() {
 }
 
 /**
- * Activity screen 'favorites' index
+ * Load the 'Favorites' activity page.
  *
  * @since BuddyPress (1.2)
  *
@@ -108,7 +112,7 @@ function bp_activity_screen_favorites() {
 }
 
 /**
- * Activity screen 'mentions' index
+ * Load the 'Mentions' activity page.
  *
  * @since BuddyPress (1.2)
  *
@@ -125,25 +129,7 @@ function bp_activity_screen_mentions() {
 }
 
 /**
- * Removes activity notifications from the notification menu when a user clicks on them and
- * is taken to a specific screen.
- *
- * @since BuddyPress (1.5)
- *
- * @global object $bp BuddyPress global settings
- * @uses bp_core_delete_notifications_by_type()
- */
-function bp_activity_remove_screen_notifications() {
-	global $bp;
-
-	bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->activity->id, 'new_at_mention' );
-}
-add_action( 'bp_activity_screen_my_activity',               'bp_activity_remove_screen_notifications' );
-add_action( 'bp_activity_screen_single_activity_permalink', 'bp_activity_remove_screen_notifications' );
-add_action( 'bp_activity_screen_mentions',                  'bp_activity_remove_screen_notifications' );
-
-/**
- * Reset the logged-in user's new mentions data when he visits his mentions screen
+ * Reset the logged-in user's new mentions data when he visits his mentions screen.
  *
  * @since BuddyPress (1.5)
  *
@@ -158,7 +144,7 @@ function bp_activity_reset_my_new_mentions() {
 add_action( 'bp_activity_screen_mentions', 'bp_activity_reset_my_new_mentions' );
 
 /**
- * Reset the logged-in user's new mentions data when he visits his mentions screen
+ * Load the page for a single activity item.
  *
  * @since BuddyPress (1.2)
  *
@@ -255,13 +241,13 @@ function bp_activity_screen_single_activity_permalink() {
 add_action( 'bp_screens', 'bp_activity_screen_single_activity_permalink' );
 
 /**
- * Add activity notifications settings to the notifications settings page
+ * Add activity notifications settings to the notifications settings page.
  *
  * @since BuddyPress (1.2)
  *
  * @uses bp_get_user_meta()
  * @uses bp_core_get_username()
- * @uses do_action() To call the 'bp_activity_screen_notification_settings' hook
+ * @uses do_action() To call the 'bp_activity_screen_notification_settings' hook.
  */
 function bp_activity_screen_notification_settings() {
 
@@ -315,7 +301,7 @@ add_action( 'bp_notification_settings', 'bp_activity_screen_notification_setting
 /** Theme Compatability *******************************************************/
 
 /**
- * The main theme compat class for BuddyPress Activity
+ * The main theme compat class for BuddyPress Activity.
  *
  * This class sets up the necessary theme compatability actions to safely output
  * activity template parts to the_title and the_content areas of a theme.
@@ -325,7 +311,7 @@ add_action( 'bp_notification_settings', 'bp_activity_screen_notification_setting
 class BP_Activity_Theme_Compat {
 
 	/**
-	 * Setup the activity component theme compatibility
+	 * Set up the activity component theme compatibility.
 	 *
 	 * @since BuddyPress (1.7)
 	 */
@@ -334,7 +320,7 @@ class BP_Activity_Theme_Compat {
 	}
 
 	/**
-	 * Are we looking at something that needs activity theme compatability?
+	 * Set up the theme compatibility hooks, if we're looking at an activity page.
 	 *
 	 * @since BuddyPress (1.7)
 	 */
@@ -371,7 +357,7 @@ class BP_Activity_Theme_Compat {
 	 *
 	 * @since BuddyPress (1.8)
 	 *
-	 * @param string $templates The templates from bp_get_theme_compat_templates()
+	 * @param string $templates The templates from bp_get_theme_compat_templates().
 	 * @return array $templates Array of custom templates to look for.
 	 */
 	public function directory_template_hierarchy( $templates ) {
@@ -388,31 +374,31 @@ class BP_Activity_Theme_Compat {
 	}
 
 	/**
-	 * Update the global $post with directory data
+	 * Update the global $post with directory data.
 	 *
 	 * @since BuddyPress (1.7)
 	 */
 	public function directory_dummy_post() {
 		bp_theme_compat_reset_post( array(
 			'ID'             => 0,
-			'post_title'     => __( 'Sitewide Activity', 'buddypress' ),
+			'post_title'     => bp_get_directory_title( 'activity' ),
 			'post_author'    => 0,
 			'post_date'      => 0,
 			'post_content'   => '',
 			'post_type'      => 'bp_activity',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
 
 	/**
-	 * Filter the_content with the groups index template part
+	 * Filter the_content with the groups index template part.
 	 *
 	 * @since BuddyPress (1.7)
 	 */
 	public function directory_content() {
-		bp_buffer_template_part( 'activity/index' );
+		return bp_buffer_template_part( 'activity/index', null, false );
 	}
 
 	/** Single ****************************************************************/
@@ -424,7 +410,7 @@ class BP_Activity_Theme_Compat {
 	 *
 	 * @since BuddyPress (1.8)
 	 *
-	 * @param string $templates The templates from bp_get_theme_compat_templates()
+	 * @param string $templates The templates from bp_get_theme_compat_templates().
 	 * @return array $templates Array of custom templates to look for.
 	 */
 	public function single_template_hierarchy( $templates ) {
@@ -441,7 +427,7 @@ class BP_Activity_Theme_Compat {
 	}
 
 	/**
-	 * Update the global $post with the displayed user's data
+	 * Update the global $post with the displayed user's data.
 	 *
 	 * @since BuddyPress (1.7)
 	 */
@@ -454,18 +440,18 @@ class BP_Activity_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => 'bp_activity',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
 
 	/**
-	 * Filter the_content with the members' activity permalink template part
+	 * Filter the_content with the members' activity permalink template part.
 	 *
 	 * @since BuddyPress (1.7)
 	 */
 	public function single_dummy_content() {
-		bp_buffer_template_part( 'activity/single/home' );
+		return bp_buffer_template_part( 'activity/single/home', null, false );
 	}
 }
 new BP_Activity_Theme_Compat();
diff --git a/wp-content/plugins/buddypress/bp-activity/bp-activity-template.php b/wp-content/plugins/buddypress/bp-activity/bp-activity-template.php
index a0dcbf11a5f79208a33e50b9bff625a3183255c4..8e28b6b43dce64b719a7036ade1ff659291a36d0 100644
--- a/wp-content/plugins/buddypress/bp-activity/bp-activity-template.php
+++ b/wp-content/plugins/buddypress/bp-activity/bp-activity-template.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Activity Template Functions
+ * BuddyPress Activity Template Functions.
  *
  * @package BuddyPress
  * @subpackage ActivityTemplate
@@ -11,7 +11,7 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Output the activity component slug
+ * Output the activity component slug.
  *
  * @since BuddyPress (1.5)
  *
@@ -21,20 +21,20 @@ function bp_activity_slug() {
 	echo bp_get_activity_slug();
 }
 	/**
-	 * Return the activity component slug
+	 * Return the activity component slug.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
-	 * @global object $bp BuddyPress global settings
-	 * @uses apply_filters() To call the 'bp_get_activity_slug' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_slug' hook.
+	 *
+	 * @return string The activity component slug.
 	 */
 	function bp_get_activity_slug() {
-		global $bp;
-		return apply_filters( 'bp_get_activity_slug', $bp->activity->slug );
+		return apply_filters( 'bp_get_activity_slug', buddypress()->activity->slug );
 	}
 
 /**
- * Output the activity component root slug
+ * Output the activity component root slug.
  *
  * @since BuddyPress (1.5)
  *
@@ -44,20 +44,20 @@ function bp_activity_root_slug() {
 	echo bp_get_activity_root_slug();
 }
 	/**
-	 * Return the activity component root slug
+	 * Return the activity component root slug.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
-	 * @global object $bp BuddyPress global settings
-	 * @uses apply_filters() To call the 'bp_get_activity_root_slug' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_root_slug' hook.
+	 *
+	 * @return string The activity component root slug.
 	 */
 	function bp_get_activity_root_slug() {
-		global $bp;
-		return apply_filters( 'bp_get_activity_root_slug', $bp->activity->root_slug );
+		return apply_filters( 'bp_get_activity_root_slug', buddypress()->activity->root_slug );
 	}
 
 /**
- * Output member directory permalink
+ * Output activity directory permalink.
  *
  * @since BuddyPress (1.5)
  *
@@ -67,25 +67,25 @@ function bp_activity_directory_permalink() {
 	echo bp_get_activity_directory_permalink();
 }
 	/**
-	 * Return member directory permalink
+	 * Return activity directory permalink
 	 *
 	 * @since BuddyPress (1.5)
 	 *
 	 * @uses traisingslashit()
 	 * @uses bp_get_root_domain()
 	 * @uses bp_get_activity_root_slug()
-	 * @uses apply_filters() To call the 'bp_get_activity_directory_permalink' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_directory_permalink' hook.
 	 *
-	 * @return string Activity directory permalink
+	 * @return string Activity directory permalink.
 	 */
 	function bp_get_activity_directory_permalink() {
 		return apply_filters( 'bp_get_activity_directory_permalink', trailingslashit( bp_get_root_domain() . '/' . bp_get_activity_root_slug() ) );
 	}
 
 /**
- * The main activity template loop
+ * The main activity template loop class.
  *
- * This is responsible for loading a group of activity items and displaying them
+ * This is responsible for loading a group of activity items and displaying them.
  *
  * @since BuddyPress (1.0)
  */
@@ -105,12 +105,31 @@ class BP_Activity_Template {
 	var $full_name;
 
 	/**
-	 * Constructor method
-	 *
-	 * See definition of $defaults below, as well as $defaults in bp_has_activities(), for
-	 * description of $args array
-	 *
-	 * @param array $args
+	 * Constructor method.
+	 *
+	 * The arguments passed to this class constructor are of the same
+	 * format as {@link BP_Activity_Activity::get()}.
+	 *
+	 * @see BP_Activity_Activity::get() for a description of the argument
+	 *      structure, as well as default values.
+	 *
+	 * @param array $args {
+	 *     Array of arguments. Supports all arguments from
+	 *     BP_Activity_Activity::get(), as well as 'page_arg' and
+	 *     'include'. Default values for 'per_page' and 'display_comments'
+	 *     differ from the originating function, and are described below.
+	 *     @type string $page_arg The string used as a query parameter in
+	 *           pagination links. Default: 'acpage'.
+	 *     @type array|bool $include Pass an array of activity IDs to
+	 *           retrieve only those items, or false to noop the 'include'
+	 *           parameter. 'include' differs from 'in' in that 'in' forms
+	 *           an IN clause that works in conjunction with other filters
+	 *           passed to the function, while 'include' is interpreted as
+	 *           an exact list of items to retrieve, which skips all other
+	 *           filter-related parameters. Default: false.
+	 *     @type int|bool $per_page Default: 20.
+	 *     @type string|bool $display_comments Default: 'threaded'.
+	 * }
 	 */
 	function __construct( $args ) {
 		global $bp;
@@ -140,20 +159,21 @@ class BP_Activity_Template {
 		}
 
 		$defaults = array(
-			'page'             => 1,
-			'per_page'         => 20,
-			'page_arg'         => 'acpage',
-			'max'              => false,
-			'sort'             => false,
-			'include'          => false,
-			'exclude'          => false,
-			'in'               => false,
-			'filter'           => false,
-			'search_terms'     => false,
-			'meta_query'       => false,
-			'display_comments' => 'threaded',
-			'show_hidden'      => false,
-			'spam'             => 'ham_only',
+			'page'              => 1,
+			'per_page'          => 20,
+			'page_arg'          => 'acpage',
+			'max'               => false,
+			'sort'              => false,
+			'include'           => false,
+			'exclude'           => false,
+			'in'                => false,
+			'filter'            => false,
+			'search_terms'      => false,
+			'meta_query'        => false,
+			'display_comments'  => 'threaded',
+			'show_hidden'       => false,
+			'spam'              => 'ham_only',
+			'update_meta_cache' => true,
 		);
 		$r = wp_parse_args( $args, $defaults );
 		extract( $r );
@@ -168,12 +188,37 @@ class BP_Activity_Template {
 		$this->my_favs = maybe_unserialize( bp_get_user_meta( bp_loggedin_user_id(), 'bp_favorite_activities', true ) );
 
 		// Fetch specific activity items based on ID's
-		if ( !empty( $include ) )
-			$this->activities = bp_activity_get_specific( array( 'activity_ids' => explode( ',', $include ), 'max' => $max, 'page' => $this->pag_page, 'per_page' => $this->pag_num, 'sort' => $sort, 'display_comments' => $display_comments, 'show_hidden' => $show_hidden, 'spam' => $spam ) );
+		if ( !empty( $include ) ) {
+			$this->activities = bp_activity_get_specific( array(
+				'activity_ids'      => explode( ',', $include ),
+				'max'               => $max,
+				'page'              => $this->pag_page,
+				'per_page'          => $this->pag_num,
+				'sort'              => $sort,
+				'display_comments'  => $display_comments,
+				'show_hidden'       => $show_hidden,
+				'spam'              => $spam,
+				'update_meta_cache' => $update_meta_cache,
+			) );
 
 		// Fetch all activity items
-		else
-			$this->activities = bp_activity_get( array( 'display_comments' => $display_comments, 'max' => $max, 'per_page' => $this->pag_num, 'page' => $this->pag_page, 'sort' => $sort, 'search_terms' => $search_terms, 'meta_query' => $meta_query, 'filter' => $filter, 'show_hidden' => $show_hidden, 'exclude' => $exclude, 'in' => $in, 'spam' => $spam ) );
+		} else {
+			$this->activities = bp_activity_get( array(
+				'display_comments'  => $display_comments,
+				'max'               => $max,
+				'per_page'          => $this->pag_num,
+				'page'              => $this->pag_page,
+				'sort'              => $sort,
+				'search_terms'      => $search_terms,
+				'meta_query'        => $meta_query,
+				'filter'            => $filter,
+				'show_hidden'       => $show_hidden,
+				'exclude'           => $exclude,
+				'in'                => $in,
+				'spam'              => $spam,
+				'update_meta_cache' => $update_meta_cache,
+			) );
+		}
 
 		if ( !$max || $max >= (int) $this->activities['total'] )
 			$this->total_activity_count = (int) $this->activities['total'];
@@ -225,6 +270,13 @@ class BP_Activity_Template {
 		}
 	}
 
+	/**
+	 * Whether there are activity items available in the loop.
+	 *
+	 * @see bp_has_activities()
+	 *
+	 * @return bool True if there are items in the loop, otherwise false.
+	 */
 	function has_activities() {
 		if ( $this->activity_count )
 			return true;
@@ -232,6 +284,11 @@ class BP_Activity_Template {
 		return false;
 	}
 
+	/**
+	 * Set up the next activity item and iterate index.
+	 *
+	 * @return object The next activity item to iterate over.
+	 */
 	function next_activity() {
 		$this->current_activity++;
 		$this->activity = $this->activities[$this->current_activity];
@@ -239,6 +296,9 @@ class BP_Activity_Template {
 		return $this->activity;
 	}
 
+	/**
+	 * Rewind the posts and reset post index.
+	 */
 	function rewind_activities() {
 		$this->current_activity = -1;
 		if ( $this->activity_count > 0 ) {
@@ -246,6 +306,18 @@ class BP_Activity_Template {
 		}
 	}
 
+	/**
+	 * Whether there are activity items left in the loop to iterate over.
+	 *
+	 * This method is used by {@link bp_activities()} as part of the while loop
+	 * that controls iteration inside the activities loop, eg:
+	 *     while ( bp_activities() ) { ...
+	 *
+	 * @see bp_activities()
+	 *
+	 * @return bool True if there are more activity items to show,
+	 *              otherwise false.
+	 */
 	function user_activities() {
 		if ( $this->current_activity + 1 < $this->activity_count ) {
 			return true;
@@ -259,6 +331,15 @@ class BP_Activity_Template {
 		return false;
 	}
 
+	/**
+	 * Set up the current activity item inside the loop.
+	 *
+	 * Used by {@link bp_the_activity()} to set up the current activity item
+	 * data while looping, so that template tags used during that iteration
+	 * make reference to the current activity item.
+	 *
+	 * @see bp_the_activity()
+	 */
 	function the_activity() {
 
 		$this->in_the_loop = true;
@@ -273,16 +354,16 @@ class BP_Activity_Template {
 }
 
 /**
- * Initializes the activity loop.
+ * Initialize the activity loop.
  *
- * Based on the $args passed, bp_has_activities() populates the $activities_template global.
+ * Based on the $args passed, bp_has_activities() populates the
+ * $activities_template global, enabling the use of BuddyPress templates and
+ * template functions to display a list of activity items.
  *
  * @since BuddyPress (1.0)
  *
- * @param array $args Arguments for limiting the contents of the activity loop. Can be passed as an associative array or as a URL argument string
- *
  * @global object $activities_template {@link BP_Activity_Template}
- * @global object $bp BuddyPress global settings
+ * @global object $bp BuddyPress global settings.
  * @uses groups_is_user_member()
  * @uses bp_current_action()
  * @uses bp_is_current_action()
@@ -293,9 +374,113 @@ class BP_Activity_Template {
  * @uses friends_get_friend_user_ids()
  * @uses groups_get_user_groups()
  * @uses bp_activity_get_user_favorites()
- * @uses apply_filters() To call the 'bp_has_activities' hook
- *
- * @return bool Returns true when activities are found
+ * @uses apply_filters() To call the 'bp_has_activities' hook.
+ *
+ * @param array $args {
+ *     Arguments for limiting the contents of the activity loop. Most
+ *     arguments are in the same format as {@link BP_Activity_Activity::get()}.
+ *     However, because the format of the arguments accepted here differs in
+ *     a number of ways, and because bp_has_activities() determines some
+ *     default arguments in a dynamic fashion, we list all accepted arguments
+ *     here as well.
+ *
+ *     Arguments can be passed as an associative array, or as a URL query
+ *     string (eg, 'user_id=4&display_comments=threaded').
+ *
+ *     @type int $page Which page of results to fetch. Using page=1 without
+ *           per_page will result in no pagination. Default: 1.
+ *     @type int|bool $per_page Number of results per page. Default: 20.
+ *     @type string $page_arg The string used as a query parameter in
+ *           pagination links. Default: 'acpage'.
+ *     @type int|bool $max Maximum number of results to return.
+ *           Default: false (unlimited).
+ *     @type string $sort 'ASC' or 'DESC'. Default: 'DESC'.
+ *     @type array|bool $exclude Array of activity IDs to exclude. Default: false.
+ *     @type array|bool $in Array of IDs to limit query by (IN). 'in' is
+ *           intended to be used in conjunction with other filter parameters.
+ *           Default: false.
+ *     @type array|bool $include Array of exact activity IDs to query.
+ *           Providing an 'include' array will override all other filters
+ *           passed in the argument array. When viewing a the permalink page
+ *           for a single activity item, this value defaults to the ID of that
+ *           item. Otherwise the default is false.
+ *     @type array $meta_query Limit by activitymeta by passing an array of
+ *           meta_query conditions. See {@link WP_Meta_Query::queries} for a
+ *           description of the syntax.
+ *     @type string $search_terms Limit results by a search term. Default: false.
+ *     @type string|bool $scope Use one of BuddyPress's pre-built filters. In
+ *           each case, the term 'current user' refers to the displayed user
+ *           when looking at a user profile, and otherwise to the logged-in user.
+ *             - 'just-me' retrieves items belonging only to the logged-in user;
+ *               this is equivalent to passing a 'user_id' argument
+ *             - 'friends' retrieves items belonging to the friends of the
+ *               current user
+ *             - 'groups' retrieves items associated with the groups to which
+ *               the current user belongs
+ *             - 'favorites' retrieves the current user's favorited activity
+ *               items
+ *             - 'mentions' retrieves activity items where the current user has
+ *               received an @-mention
+ *           The default value of 'scope' is set to one of the above if that
+ *           value appears in the appropriate place in the URL; eg, 'scope' will
+ *           be 'groups' when visiting http://example.com/members/joe/activity/groups/.
+ *           Otherwise defaults to false.
+ *     @type int|array|bool $user_id The ID(s) of user(s) whose activity should
+ *           be fetched. Pass a single ID or an array of IDs. When viewing a
+ *           user profile page (but not that user's activity subpages, ie My
+ *           Friends, My Groups, etc), 'user_id' defaults to the ID of the
+ *           displayed user. Otherwise the default is false.
+ *     @type string|array|bool $object Filters by the `component` column in the
+ *           database, which is generally the component ID in the case of
+ *           BuddyPress components, or the plugin slug in the case of plugins.
+ *           For example, 'groups' will limit results to those that are
+ *           associated with the BP Groups component. Accepts a single
+ *           component string, or an array of multiple components. Defaults to
+ *           'groups' when viewing the page of a single group, the My Groups
+ *           activity filter, or the Activity > Groups filter of a user profile.
+ *           Otherwise defaults to false.
+ *     @type string|array|bool $action Filters by the `type` column in the
+ *           database, which is a string categorizing the activity item (eg,
+ *           'new_blog_post', 'created_group'). Accepts a single type string,
+ *           or an array of multiple types. Defaults to false.
+ *     @type int|array|bool $primary_id Filters by the `item_id` column in the
+ *           database. The meaning of 'primary_id' differs between components/
+ *           types; for example, in the case of 'created_group', 'primary_id'
+ *           is the ID of the group. Accepts a single ID, or an array of
+ *           multiple IDs. When viewing a single group, defaults to the current
+ *           group ID. When viewing a user's Groups stream page, defaults to
+ *           the IDs of the user's groups. Otherwise defaults to false.
+ *     @type int|array|bool $secondary_id Filters by the `secondary_item_id`
+ *           column in the database. The meaning of 'secondary_id' differs
+ *           between components/types. Accepts a single ID, or an array of
+ *           multiple IDs. Defaults to false.
+ *     @type int $offset Return only activity items with an ID greater than or
+ *           equal to this one. Note that providing an offset will disable
+ *           pagination. Default: false.
+ *     @type string|bool $display_comments How to handle activity comments.
+ *           Possible values:
+ *             - 'threaded' - comments appear in a threaded tree, under their
+ *               parent items
+ *             - 'stream' - the activity stream is presented in a flat manner,
+ *               with comments sorted in chronological order alongside other
+ *               activity items
+ *             - false - don't fetch activity comments at all
+ *           Default: 'threaded'.
+ *     @type bool $show_hidden Whether to show items marked hide_sitewide.
+ *           Defaults to false, except in the following cases:
+ *             - User is viewing his own activity stream
+ *             - User is viewing the activity stream of a non-public group of
+ *               which he is a member
+ *     @type bool $show_hidden Normally defaults to false, except when:
+ *             - a user is viewing his own activity stream
+ *             - a user is viewing the activity stream of a non-public group of
+ *               which he is a member
+ *     @type string|bool $spam Spam status. 'ham_only', 'spam_only', or false
+ *           to show all activity regardless of spam status. Default: 'ham_only'.
+ *     @type bool $populate_extras Whether to pre-fetch the activity metadata
+ *           for the queried items. Default: true.
+ * }
+ * @return bool Returns true when activities are found, otherwise false.
  */
 function bp_has_activities( $args = '' ) {
 	global $activities_template, $bp;
@@ -339,38 +524,53 @@ function bp_has_activities( $args = '' ) {
 
 	// Note: any params used for filtering can be a single value, or multiple values comma separated.
 	$defaults = array(
-		'display_comments' => 'threaded',   // false for none, stream/threaded - show comments in the stream or threaded under items
-		'include'          => $include,     // pass an activity_id or string of IDs comma-separated
-		'exclude'          => $exclude,     // pass an activity_id or string of IDs comma-separated
-		'in'               => $in,          // comma-separated list or array of activity IDs among which to search
-		'sort'             => 'DESC',       // sort DESC or ASC
-		'page'             => 1,            // which page to load
-		'per_page'         => 20,           // number of items per page
-		'max'              => false,        // max number to return
-		'show_hidden'      => $show_hidden, // Show activity items that are hidden site-wide?
-		'spam'             => 'ham_only',   // Hide spammed items
-
-		'page_arg'         => 'acpage',     // See https://buddypress.trac.wordpress.org/ticket/3679
+		'display_comments'  => 'threaded',   // false for none, stream/threaded - show comments in the stream or threaded under items
+		'include'           => $include,     // pass an activity_id or string of IDs comma-separated
+		'exclude'           => $exclude,     // pass an activity_id or string of IDs comma-separated
+		'in'                => $in,          // comma-separated list or array of activity IDs among which to search
+		'sort'              => 'DESC',       // sort DESC or ASC
+		'page'              => 1,            // which page to load
+		'per_page'          => 20,           // number of items per page
+		'max'               => false,        // max number to return
+		'show_hidden'       => $show_hidden, // Show activity items that are hidden site-wide?
+		'spam'              => 'ham_only',   // Hide spammed items
+
+		'page_arg'          => 'acpage',     // See https://buddypress.trac.wordpress.org/ticket/3679
 
 		// Scope - pre-built activity filters for a user (friends/groups/favorites/mentions)
-		'scope'            => $scope,
+		'scope'             => $scope,
 
 		// Filtering
-		'user_id'          => $user_id,     // user_id to filter on
-		'object'           => $object,      // object to filter on e.g. groups, profile, status, friends
-		'action'           => false,        // action to filter on e.g. activity_update, new_forum_post, profile_updated
-		'primary_id'       => $primary_id,  // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
-		'secondary_id'     => false,        // secondary object ID to filter on e.g. a post_id
+		'user_id'           => $user_id,     // user_id to filter on
+		'object'            => $object,      // object to filter on e.g. groups, profile, status, friends
+		'action'            => false,        // action to filter on e.g. activity_update, new_forum_post, profile_updated
+		'primary_id'        => $primary_id,  // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
+		'secondary_id'      => false,        // secondary object ID to filter on e.g. a post_id
+		'offset'            => false,        // return only items >= this ID
+		'since'             => false,        // return only items recorded since this Y-m-d H:i:s date
 
-		'meta_query'       => false,        // filter on activity meta. See WP_Meta_Query for format
+		'meta_query'        => false,        // filter on activity meta. See WP_Meta_Query for format
 
 		// Searching
-		'search_terms'     => false         // specify terms to search on
+		'search_terms'      => false,        // specify terms to search on
+		'update_meta_cache' => true,
 	);
 
-	$r = wp_parse_args( $args, $defaults );
+	$r = bp_parse_args( $args, $defaults, 'has_activities' );
 	extract( $r );
 
+	// Translate various values for 'display_comments'
+	// This allows disabling comments via ?display_comments=0
+	// or =none or =false. Final true is a strict type check. See #5029
+	if ( in_array( $display_comments, array( 0, '0', 'none', 'false' ), true ) ) {
+		$display_comments = false;
+	}
+
+	// Ignore pagination if an offset is passed
+	if ( ! empty( $offset ) ) {
+		$page = 0;
+	}
+
 	if ( empty( $search_terms ) && ! empty( $_REQUEST['s'] ) )
 		$search_terms = $_REQUEST['s'];
 
@@ -425,7 +625,7 @@ function bp_has_activities( $args = '' ) {
 					}
 
 					// Start search at @ symbol and stop search at closing tag delimiter.
-					$search_terms     = '@' . bp_core_get_username( $user_id ) . '<';
+					$search_terms     = '@' . bp_activity_get_user_mentionname( $user_id ) . '<';
 					$display_comments = 'stream';
 					$user_id = 0;
 					break;
@@ -442,8 +642,8 @@ function bp_has_activities( $args = '' ) {
 	// into bp-custom.php or your theme's functions.php
 	if ( isset( $_GET['afilter'] ) && apply_filters( 'bp_activity_enable_afilter_support', false ) )
 		$filter = array( 'object' => $_GET['afilter'] );
-	else if ( !empty( $user_id ) || !empty( $object ) || !empty( $action ) || !empty( $primary_id ) || !empty( $secondary_id ) )
-		$filter = array( 'user_id' => $user_id, 'object' => $object, 'action' => $action, 'primary_id' => $primary_id, 'secondary_id' => $secondary_id );
+	else if ( ! empty( $user_id ) || ! empty( $object ) || ! empty( $action ) || ! empty( $primary_id ) || ! empty( $secondary_id ) || ! empty( $offset ) || ! empty( $since ) )
+		$filter = array( 'user_id' => $user_id, 'object' => $object, 'action' => $action, 'primary_id' => $primary_id, 'secondary_id' => $secondary_id, 'offset' => $offset, 'since' => $since );
 	else
 		$filter = false;
 
@@ -452,20 +652,21 @@ function bp_has_activities( $args = '' ) {
 		$spam = 'all';
 
 	$template_args = array(
-		'page'             => $page,
-		'per_page'         => $per_page,
-		'page_arg'         => $page_arg,
-		'max'              => $max,
-		'sort'             => $sort,
-		'include'          => $include,
-		'exclude'          => $exclude,
-		'in'               => $in,
-		'filter'           => $filter,
-		'search_terms'     => $search_terms,
-		'meta_query'       => $meta_query,
-		'display_comments' => $display_comments,
-		'show_hidden'      => $show_hidden,
-		'spam'             => $spam
+		'page'              => $page,
+		'per_page'          => $per_page,
+		'page_arg'          => $page_arg,
+		'max'               => $max,
+		'sort'              => $sort,
+		'include'           => $include,
+		'exclude'           => $exclude,
+		'in'                => $in,
+		'filter'            => $filter,
+		'search_terms'      => $search_terms,
+		'meta_query'        => $meta_query,
+		'display_comments'  => $display_comments,
+		'show_hidden'       => $show_hidden,
+		'spam'              => $spam,
+		'update_meta_cache' => $update_meta_cache,
 	);
 
 	$activities_template = new BP_Activity_Template( $template_args );
@@ -474,14 +675,14 @@ function bp_has_activities( $args = '' ) {
 }
 
 /**
- * Determines if there are still activities left in the loop.
+ * Determine if there are still activities left in the loop.
  *
  * @since BuddyPress (1.0)
  *
  * @global object $activities_template {@link BP_Activity_Template}
  * @uses BP_Activity_Template::user_activities() {@link BP_Activity_Template::user_activities()}
  *
- * @return bool Returns true when activities are found
+ * @return bool Returns true when activities are found.
  */
 function bp_activities() {
 	global $activities_template;
@@ -489,14 +690,14 @@ function bp_activities() {
 }
 
 /**
- * Gets the current activity object in the loop
+ * Get the current activity object in the loop.
  *
  * @since BuddyPress (1.0)
  *
  * @global object $activities_template {@link BP_Activity_Template}
  * @uses BP_Activity_Template::the_activity() {@link BP_Activity_Template::the_activity()}
  *
- * @return object The current activity within the loop
+ * @return object The current activity within the loop.
  */
 function bp_the_activity() {
 	global $activities_template;
@@ -504,7 +705,7 @@ function bp_the_activity() {
 }
 
 /**
- * Outputs the activity pagination count
+ * Output the activity pagination count.
  *
  * @since BuddyPress (1.0)
  *
@@ -516,14 +717,14 @@ function bp_activity_pagination_count() {
 }
 
 	/**
-	 * Returns the activity pagination count
+	 * Return the activity pagination count.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 * @uses bp_core_number_format()
 	 *
-	 * @return string The pagination text
+	 * @return string The pagination text.
 	 */
 	function bp_get_activity_pagination_count() {
 		global $activities_template;
@@ -533,11 +734,11 @@ function bp_activity_pagination_count() {
 		$to_num    = bp_core_number_format( ( $start_num + ( $activities_template->pag_num - 1 ) > $activities_template->total_activity_count ) ? $activities_template->total_activity_count : $start_num + ( $activities_template->pag_num - 1 ) );
 		$total     = bp_core_number_format( $activities_template->total_activity_count );
 
-		return sprintf( __( 'Viewing item %1$s to %2$s (of %3$s items)', 'buddypress' ), $from_num, $to_num, $total );
+		return sprintf( _n( 'Viewing item %1$s to %2$s (of %3$s item)', 'Viewing item %1$s to %2$s (of %3$s items)', $total, 'buddypress' ), $from_num, $to_num, $total );
 	}
 
 /**
- * Outputs the activity pagination links
+ * Output the activity pagination links.
  *
  * @since BuddyPress (1.0)
  *
@@ -548,14 +749,14 @@ function bp_activity_pagination_links() {
 }
 
 	/**
-	 * Outputs the activity pagination links
+	 * Return the activity pagination links.
 	 *
 	 * @since BuddyPress (1.0)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_pagination_links' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_pagination_links' hook.
 	 *
-	 * @return string The pagination links
+	 * @return string The pagination links.
 	 */
 	function bp_get_activity_pagination_links() {
 		global $activities_template;
@@ -564,26 +765,31 @@ function bp_activity_pagination_links() {
 	}
 
 /**
- * Returns true when there are more activity items to be shown than currently appear
+ * Return true when there are more activity items to be shown than currently appear.
  *
  * @since BuddyPress (1.5)
  *
  * @global object $activities_template {@link BP_Activity_Template}
- * @uses apply_filters() To call the 'bp_activity_has_more_items' hook
+ * @uses apply_filters() To call the 'bp_activity_has_more_items' hook.
  *
- * @return bool $has_more_items True if more items, false if not
+ * @return bool $has_more_items True if more items, false if not.
  */
 function bp_activity_has_more_items() {
 	global $activities_template;
 
-	$remaining_pages = floor( ( $activities_template->total_activity_count - 1 ) / ( $activities_template->pag_num * $activities_template->pag_page ) );
+	$remaining_pages = 0;
+
+	if ( ! empty( $activities_template->pag_page ) ) {
+		$remaining_pages = floor( ( $activities_template->total_activity_count - 1 ) / ( $activities_template->pag_num * $activities_template->pag_page ) );
+	}
+
 	$has_more_items  = (int) $remaining_pages ? true : false;
 
 	return apply_filters( 'bp_activity_has_more_items', $has_more_items );
 }
 
 /**
- * Outputs the activity count
+ * Output the activity count.
  *
  * @since BuddyPress (1.2)
  *
@@ -594,14 +800,14 @@ function bp_activity_count() {
 }
 
 	/**
-	 * Returns the activity count
+	 * Return the activity count.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_count' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_count' hook.
 	 *
-	 * @return int The activity count
+	 * @return int The activity count.
 	 */
 	function bp_get_activity_count() {
 		global $activities_template;
@@ -610,7 +816,7 @@ function bp_activity_count() {
 	}
 
 /**
- * Outputs the number of activities per page
+ * Output the number of activities per page.
  *
  * @since BuddyPress (1.2)
  *
@@ -621,14 +827,14 @@ function bp_activity_per_page() {
 }
 
 	/**
-	 * Returns the number of activities per page
+	 * Return the number of activities per page.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_per_page' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_per_page' hook.
 	 *
-	 * @return int The activities per page
+	 * @return int The activities per page.
 	 */
 	function bp_get_activity_per_page() {
 		global $activities_template;
@@ -637,25 +843,27 @@ function bp_activity_per_page() {
 	}
 
 /**
- * Outputs the activities title
+ * Output the activities title.
  *
  * @since BuddyPress (1.0)
  *
  * @uses bp_get_activities_title()
+ * @todo Deprecate.
  */
 function bp_activities_title() {
 	echo bp_get_activities_title();
 }
 
 	/**
-	 * Returns the activities title
+	 * Return the activities title.
 	 *
 	 * @since BuddyPress (1.0)
 	 *
 	 * @global string $bp_activity_title
-	 * @uses apply_filters() To call the 'bp_get_activities_title' hook
+	 * @uses apply_filters() To call the 'bp_get_activities_title' hook.
+	 * @todo Deprecate.
 	 *
-	 * @return int The activities title
+	 * @return int The activities title.
 	 */
 	function bp_get_activities_title() {
 		global $bp_activity_title;
@@ -669,6 +877,7 @@ function bp_activities_title() {
  * @since BuddyPress (1.0)
  *
  * @uses bp_get_activities_no_activity()
+ * @todo Deprecate.
  */
 function bp_activities_no_activity() {
 	echo bp_get_activities_no_activity();
@@ -681,6 +890,7 @@ function bp_activities_no_activity() {
 	 *
 	 * @global string $bp_activity_no_activity
 	 * @uses apply_filters() To call the 'bp_get_activities_no_activity' hook
+	 * @todo Deprecate.
 	 *
 	 * @return string
 	 */
@@ -691,7 +901,7 @@ function bp_activities_no_activity() {
 	}
 
 /**
- * Outputs the activity id
+ * Output the activity ID.
  *
  * @since BuddyPress (1.2)
  *
@@ -702,14 +912,14 @@ function bp_activity_id() {
 }
 
 	/**
-	 * Returns the activity id
+	 * Return the activity ID.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_id' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_id' hook.
 	 *
-	 * @return int The activity id
+	 * @return int The activity ID.
 	 */
 	function bp_get_activity_id() {
 		global $activities_template;
@@ -717,7 +927,7 @@ function bp_activity_id() {
 	}
 
 /**
- * Outputs the activity item id
+ * Output the activity item ID.
  *
  * @since BuddyPress (1.2)
  *
@@ -728,14 +938,14 @@ function bp_activity_item_id() {
 }
 
 	/**
-	 * Returns the activity item id
+	 * Return the activity item ID.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_item_id' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_item_id' hook.
 	 *
-	 * @return int The activity item id
+	 * @return int The activity item ID.
 	 */
 	function bp_get_activity_item_id() {
 		global $activities_template;
@@ -743,7 +953,7 @@ function bp_activity_item_id() {
 	}
 
 /**
- * Outputs the activity secondary item id
+ * Output the activity secondary item ID.
  *
  * @since BuddyPress (1.2)
  *
@@ -754,14 +964,14 @@ function bp_activity_secondary_item_id() {
 }
 
 	/**
-	 * Returns the activity secondary item id
+	 * Return the activity secondary item ID.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_secondary_item_id' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_secondary_item_id' hook.
 	 *
-	 * @return int The activity secondary item id
+	 * @return int The activity secondary item ID.
 	 */
 	function bp_get_activity_secondary_item_id() {
 		global $activities_template;
@@ -769,7 +979,7 @@ function bp_activity_secondary_item_id() {
 	}
 
 /**
- * Outputs the date the activity was recorded
+ * Output the date the activity was recorded.
  *
  * @since BuddyPress (1.2)
  *
@@ -780,14 +990,14 @@ function bp_activity_date_recorded() {
 }
 
 	/**
-	 * Returns the date the activity was recorded
+	 * Return the date the activity was recorded.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_date_recorded' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_date_recorded' hook.
 	 *
-	 * @return string The date the activity was recorded
+	 * @return string The date the activity was recorded.
 	 */
 	function bp_get_activity_date_recorded() {
 		global $activities_template;
@@ -795,7 +1005,7 @@ function bp_activity_date_recorded() {
 	}
 
 /**
- * Outputs the activity object name
+ * Output the activity object name.
  *
  * @since BuddyPress (1.2)
  *
@@ -806,14 +1016,14 @@ function bp_activity_object_name() {
 }
 
 	/**
-	 * Returns the activity object name
+	 * Return the activity object name.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_object_name' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_object_name' hook.
 	 *
-	 * @return string The activity object name
+	 * @return string The activity object name.
 	 */
 	function bp_get_activity_object_name() {
 		global $activities_template;
@@ -821,7 +1031,7 @@ function bp_activity_object_name() {
 	}
 
 /**
- * Outputs the activity type
+ * Output the activity type.
  *
  * @since BuddyPress (1.2)
  *
@@ -832,14 +1042,14 @@ function bp_activity_type() {
 }
 
 	/**
-	 * Returns the activity type
+	 * Return the activity type.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_type' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_type' hook.
 	 *
-	 * @return string The activity type
+	 * @return string The activity type.
 	 */
 	function bp_get_activity_type() {
 		global $activities_template;
@@ -847,9 +1057,9 @@ function bp_activity_type() {
 	}
 
 	/**
-	 * Outputs the activity action name
+	 * Output the activity action name.
 	 *
-	 * Just a wrapper for bp_activity_type()
+	 * Just a wrapper for bp_activity_type().
 	 *
 	 * @since BuddyPress (1.2)
 	 * @deprecated BuddyPress (1.5)
@@ -862,23 +1072,23 @@ function bp_activity_type() {
 	function bp_activity_action_name() { echo bp_activity_type(); }
 
 	/**
-	 * Returns the activity type
+	 * Return the activity type.
 	 *
-	 * Just a wrapper for bp_get_activity_type()
+	 * Just a wrapper for bp_get_activity_type().
 	 *
 	 * @since BuddyPress (1.2)
 	 * @deprecated BuddyPress (1.5)
 	 *
-	 * @todo Properly deprecate in favor of bp_get_activity_type()
+	 * @todo Properly deprecate in favor of bp_get_activity_type().
 	 *
 	 * @uses bp_get_activity_type()
 	 *
-	 * @return string The activity type
+	 * @return string The activity type.
 	 */
 	function bp_get_activity_action_name() { return bp_get_activity_type(); }
 
 /**
- * Outputs the activity user id
+ * Output the activity user ID.
  *
  * @since BuddyPress (1.1)
  *
@@ -889,14 +1099,14 @@ function bp_activity_user_id() {
 }
 
 	/**
-	 * Returns the activity user id
+	 * Return the activity user ID.
 	 *
 	 * @since BuddyPress (1.1)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_user_id' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_user_id' hook.
 	 *
-	 * @return int The activity user id
+	 * @return int The activity user ID.
 	 */
 	function bp_get_activity_user_id() {
 		global $activities_template;
@@ -904,7 +1114,7 @@ function bp_activity_user_id() {
 	}
 
 /**
- * Outputs the activity user link
+ * Output the activity user link.
  *
  * @since BuddyPress (1.2)
  *
@@ -915,15 +1125,15 @@ function bp_activity_user_link() {
 }
 
 	/**
-	 * Returns the activity user link
+	 * Return the activity user link.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 * @uses bp_core_get_user_domain()
-	 * @uses apply_filters() To call the 'bp_get_activity_user_link' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_user_link' hook.
 	 *
-	 * @return string $link The activity user link
+	 * @return string $link The activity user link.
 	 */
 	function bp_get_activity_user_link() {
 		global $activities_template;
@@ -937,24 +1147,24 @@ function bp_activity_user_link() {
 	}
 
 /**
- * Output the avatar of the user that performed the action
+ * Output the avatar of the user that performed the action.
  *
  * @since BuddyPress (1.1)
  *
- * @param array $args
- *
+ * @see bp_get_activity_avatar() for description of arguments.
  * @uses bp_get_activity_avatar()
+ *
+ * @param array $args See {@link bp_get_activity_avatar()} for description.
  */
 function bp_activity_avatar( $args = '' ) {
 	echo bp_get_activity_avatar( $args );
 }
 	/**
-	 * Return the avatar of the user that performed the action
+	 * Return the avatar of the user that performed the action.
 	 *
 	 * @since BuddyPress (1.1)
 	 *
-	 * @param array $args optional
-	 *
+	 * @see bp_core_fetch_avatar() For a description of the arguments.
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 * @global object $bp BuddyPress global settings
 	 * @uses bp_is_single_activity()
@@ -964,7 +1174,20 @@ function bp_activity_avatar( $args = '' ) {
 	 * @uses bp_core_fetch_avatar()
 	 * @uses apply_filters() To call the 'bp_get_activity_avatar' hook
 	 *
-	 * @return string User avatar
+	 * @param array $args  {
+	 *     Arguments are listed here with an explanation of their defaults.
+	 *     For more information about the arguments, see
+	 *     {@link bp_core_fetch_avatar()}.
+	 *     @type string $alt Default: 'Profile picture of [user name]' if
+	 *           activity user name is available, otherwise 'Profile picture'.
+	 *     @type string $class Default: 'avatar'.
+	 *     @type string|bool $email Default: Email of the activity's
+	 *           associated user, if available. Otherwise false.
+	 *     @type string $type Default: 'full' when viewing a single activity
+	 *           permalink page, otherwise 'thumb'.
+	 *     @type int|bool $user_id Default: ID of the activity's user.
+	 * }
+	 * @return string User avatar string.
 	 */
 	function bp_get_activity_avatar( $args = '' ) {
 		global $activities_template;
@@ -1034,13 +1257,14 @@ function bp_activity_avatar( $args = '' ) {
 	}
 
 /**
- * Output the avatar of the object that action was performed on
+ * Output the avatar of the object that action was performed on.
  *
  * @since BuddyPress (1.2)
  *
- * @param array $args optional
- *
+ * @see bp_get_activity_secondary_avatar() for description of arguments.
  * @uses bp_get_activity_secondary_avatar()
+ *
+ * @param array $args See {@link bp_get_activity_secondary_avatar} for description.
  */
 function bp_activity_secondary_avatar( $args = '' ) {
 	echo bp_get_activity_secondary_avatar( $args );
@@ -1051,16 +1275,25 @@ function bp_activity_secondary_avatar( $args = '' ) {
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @param array $args optional
-	 *
+	 * @see bp_core_fetch_avatar() for description of arguments.
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 * @uses wp_parse_args()
 	 * @uses get_blog_option()
-	 * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar_object_' . $activities_template->activity->component hook
-	 * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar_item_id' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar_object_' . $activities_template->activity->component hook.
+	 * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar_item_id' hook.
 	 * @uses bp_core_fetch_avatar()
-	 * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar' hook
-	 *
+	 * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar' hook.
+	 *
+	 * @param array $args  {
+	 *     For a complete description of arguments, see {@link bp_core_fetch_avatar()}.
+	 *     @type string $alt Default value varies based on current activity
+	 *           item component.
+	 *     @type string $type Default: 'full' when viewing a single activity
+	 *           permalink page, otherwise 'thumb'.
+	 *     @type string $class Default: 'avatar'.
+	 *     @type string|bool $email Default: email of the activity's user.
+	 *     @type int|bool $user_id Default: ID of the activity's user.
+	 * }
 	 * @return string The secondary avatar
 	 */
 	function bp_get_activity_secondary_avatar( $args = '' ) {
@@ -1088,7 +1321,11 @@ function bp_activity_secondary_avatar( $args = '' ) {
 
 				// Only if groups is active
 				if ( bp_is_active( 'groups' ) ) {
-					$group = groups_get_group( array( 'group_id' => $item_id ) );
+					$group = groups_get_group( array(
+						'group_id'          => $item_id,
+						'populate_extras'   => false,
+						'update_meta_cache' => false,
+					) );
 					$link  = bp_get_group_permalink( $group );
 					$name  = $group->name;
 				}
@@ -1191,9 +1428,12 @@ function bp_activity_action( $args = array() ) {
 	 * @param array $args Only parameter is "no_timestamp". If true, timestamp is shown in output.
 	 * @uses apply_filters_ref_array() To call the 'bp_get_activity_action_pre_meta' hook
 	 * @uses bp_insert_activity_meta()
-	 * @uses apply_filters_ref_array() To call the 'bp_get_activity_action' hook
+	 * @uses apply_filters_ref_array() To call the 'bp_get_activity_action' hook.
 	 *
-	 * @return string The activity action
+	 * @param array $args {
+	 *     @type bool $no_timestamp Whether to exclude the timestamp.
+	 * }
+	 * @return string The activity action.
 	 */
 	function bp_get_activity_action( $args = array() ) {
 		global $activities_template;
@@ -1232,9 +1472,9 @@ function bp_activity_content_body() {
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 * @uses bp_insert_activity_meta()
-	 * @uses apply_filters_ref_array() To call the 'bp_get_activity_content_body' hook
+	 * @uses apply_filters_ref_array() To call the 'bp_get_activity_content_body' hook.
 	 *
-	 * @return string The activity content body
+	 * @return string The activity content body.
 	 */
 	function bp_get_activity_content_body() {
 		global $activities_template;
@@ -1253,7 +1493,7 @@ function bp_activity_content_body() {
  *
  * @global object $activities_template {@link BP_Activity_Template}
  *
- * @return bool True if activity has content, false otherwise
+ * @return bool True if activity has content, false otherwise.
  */
 function bp_activity_has_content() {
 	global $activities_template;
@@ -1265,12 +1505,12 @@ function bp_activity_has_content() {
 }
 
 /**
- * Output the activity content
+ * Output the activity content.
  *
  * @since BuddyPress (1.0)
  * @deprecated BuddyPress (1.5)
  *
- * @todo properly deprecate this function
+ * @todo properly deprecate this function.
  *
  * @uses bp_get_activity_content()
  */
@@ -1279,18 +1519,18 @@ function bp_activity_content() {
 }
 
 	/**
-	 * Return the activity content
+	 * Return the activity content.
 	 *
 	 * @since BuddyPress (1.0)
 	 * @deprecated BuddyPress (1.5)
 	 *
-	 * @todo properly deprecate this function
+	 * @todo properly deprecate this function.
 	 *
 	 * @uses bp_get_activity_action()
 	 * @uses bp_get_activity_content_body()
-	 * @uses apply_filters() To call the 'bp_get_activity_content' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_content' hook.
 	 *
-	 * @return string The activity content
+	 * @return string The activity content.
 	 */
 	function bp_get_activity_content() {
 		/**
@@ -1305,22 +1545,24 @@ function bp_activity_content() {
 	}
 
 /**
- * Insert activity meta
+ * Attach metadata about an activity item to the activity content.
  *
- * @since BuddyPress (1.2)
+ * This metadata includes the time since the item was posted (which will appear
+ * as a link to the item's permalink).
  *
- * @param string $content
+ * @since BuddyPress (1.2)
  *
  * @global object $activities_template {@link BP_Activity_Template}
  * @uses bp_core_time_since()
- * @uses apply_filters_ref_array() To call the 'bp_activity_time_since' hook
+ * @uses apply_filters_ref_array() To call the 'bp_activity_time_since' hook.
  * @uses bp_is_single_activity()
  * @uses bp_activity_get_permalink()
  * @uses esc_attr__()
- * @uses apply_filters_ref_array() To call the 'bp_activity_permalink' hook
- * @uses apply_filters() To call the 'bp_insert_activity_meta' hook
+ * @uses apply_filters_ref_array() To call the 'bp_activity_permalink' hook.
+ * @uses apply_filters() To call the 'bp_insert_activity_meta' hook.
  *
- * @return string The activity content
+ * @param string $content The activity content.
+ * @return string The activity content with the metadata string attached.
  */
 function bp_insert_activity_meta( $content ) {
 	global $activities_template;
@@ -1341,16 +1583,15 @@ function bp_insert_activity_meta( $content ) {
 }
 
 /**
- * Determine if the current user can delete an activity item
+ * Determine if the current user can delete an activity item.
  *
  * @since BuddyPress (1.2)
  *
- * @param object $activity Optional
- *
  * @global object $activities_template {@link BP_Activity_Template}
  * @uses apply_filters() To call the 'bp_activity_user_can_delete' hook
  *
- * @return bool True if can delete, false otherwise
+ * @param object $activity Optional. Falls back on the current item in the loop.
+ * @return bool True if can delete, false otherwise.
  */
 function bp_activity_user_can_delete( $activity = false ) {
 	global $activities_template;
@@ -1372,33 +1613,36 @@ function bp_activity_user_can_delete( $activity = false ) {
 	if ( bp_is_item_admin() && bp_is_single_item() )
 		$can_delete = true;
 
-	return apply_filters( 'bp_activity_user_can_delete', $can_delete );
+	return apply_filters( 'bp_activity_user_can_delete', $can_delete, $activity );
 }
 
 /**
- * Output the activity parent content
+ * Output the activity parent content.
  *
  * @since BuddyPress (1.2)
  *
- * @param array $args Optional
- *
+ * @see bp_get_activity_parent_content() for a description of arguments.
  * @uses bp_get_activity_parent_content()
+ *
+ * @param array $args See {@link bp_get_activity_parent_content} for description.
  */
 function bp_activity_parent_content( $args = '' ) {
 	echo bp_get_activity_parent_content($args);
 }
 
 	/**
-	 * Return the activity content
+	 * Return the activity content.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @param array $args Optional
-	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 * @uses wp_parse_args()
-	 * @uses apply_filters() To call the 'bp_get_activity_parent_content' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_parent_content' hook.
 	 *
+	 * @param array $args {
+	 *     Array of optional arguments.
+	 *     @deprecated bool $hide_user No longer used.
+	 * }
 	 * @return mixed False on failure, otherwise the activity parent content
 	 */
 	function bp_get_activity_parent_content( $args = '' ) {
@@ -1440,7 +1684,7 @@ function bp_activity_parent_content( $args = '' ) {
 	}
 
 /**
- * Output the parent activity's user ID
+ * Output the parent activity's user ID.
  *
  * @since BuddyPress (1.7)
  */
@@ -1449,11 +1693,14 @@ function bp_activity_parent_user_id() {
 }
 
 	/**
-	 * Return the parent activity's user ID
+	 * Return the parent activity's user ID.
 	 *
-	 * @global BP_Activity_Template $activities_template
-	 * @return bool|int False if parent activity can't be found, otherwise returns the parent activity's user ID
 	 * @since BuddyPress (1.7)
+	 *
+	 * @global BP_Activity_Template $activities_template
+	 *
+	 * @return bool|int False if parent activity can't be found, otherwise
+	 *         the parent activity's user ID.
 	 */
 	function bp_get_activity_parent_user_id() {
 		global $activities_template;
@@ -1480,7 +1727,7 @@ function bp_activity_parent_user_id() {
 	}
 
 /**
- * Output whether or not the current activity is in a current user's favorites
+ * Output whether or not the current activity is in a current user's favorites.
  *
  * @since BuddyPress (1.2)
  *
@@ -1491,14 +1738,14 @@ function bp_activity_is_favorite() {
 }
 
 	/**
-	 * Return whether or not the current activity is in a current user's favorites
+	 * Return whether the current activity is in a current user's favorites.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_is_favorite' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_is_favorite' hook.
 	 *
-	 * @return bool True if user favorite, false otherwise
+	 * @return bool True if user favorite, false otherwise.
 	 */
 	function bp_get_activity_is_favorite() {
 		global $activities_template;
@@ -1507,7 +1754,7 @@ function bp_activity_is_favorite() {
 	}
 
 /**
- * Echoes the comment markup for an activity item
+ * Output the comment markup for an activity item.
  *
  * @since BuddyPress (1.2)
  *
@@ -1520,7 +1767,7 @@ function bp_activity_comments( $args = '' ) {
 }
 
 	/**
-	 * Gets the comment markup for an activity item
+	 * Get the comment markup for an activity item.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
@@ -1551,8 +1798,6 @@ function bp_activity_comments( $args = '' ) {
 		 *
 		 * @since BuddyPress (1.2)
 		 *
-		 * @todo remove $counter global
-		 *
 		 * @param object $comment The activity object currently being recursed
 		 *
 		 * @global object $activities_template {@link BP_Activity_Template}
@@ -1579,7 +1824,7 @@ function bp_activity_comments( $args = '' ) {
 				// older themes (which are not children of bp-default and won't
 				// have the new template) will still work.
 				if ( !$template ) {
-					$template = BP_PLUGIN_DIR . '/bp-themes/bp-default/activity/comment.php';
+					$template = buddypress()->plugin_dir . '/bp-themes/bp-default/activity/comment.php';
 				}
 
 				load_template( $template, false );
@@ -1590,14 +1835,15 @@ function bp_activity_comments( $args = '' ) {
 		}
 
 /**
- * Utility function that returns the comment currently being recursed
+ * Utility function that returns the comment currently being recursed.
  *
  * @since BuddyPress (1.5)
  *
  * @global object $activities_template {@link BP_Activity_Template}
- * @uses apply_filters() To call the 'bp_activity_current_comment' hook
+ * @uses apply_filters() To call the 'bp_activity_current_comment' hook.
  *
- * @return object|bool $current_comment The activity comment currently being displayed. False on failure
+ * @return object|bool $current_comment The activity comment currently being
+ *         displayed. False on failure.
  */
 function bp_activity_current_comment() {
 	global $activities_template;
@@ -1609,7 +1855,7 @@ function bp_activity_current_comment() {
 
 
 /**
- * Echoes the id of the activity comment currently being displayed
+ * Output the ID of the activity comment currently being displayed.
  *
  * @since BuddyPress (1.5)
  *
@@ -1620,14 +1866,15 @@ function bp_activity_comment_id() {
 }
 
 	/**
-	 * Gets the id of the activity comment currently being displayed
+	 * Return the ID of the activity comment currently being displayed.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_activity_comment_id' hook
+	 * @uses apply_filters() To call the 'bp_activity_comment_id' hook.
 	 *
-	 * @return int $comment_id The id of the activity comment currently being displayed
+	 * @return int|bool $comment_id The ID of the activity comment
+	 *         currently being displayed, false if none is found.
 	 */
 	function bp_get_activity_comment_id() {
 		global $activities_template;
@@ -1638,7 +1885,7 @@ function bp_activity_comment_id() {
 	}
 
 /**
- * Echoes the user_id of the author of the activity comment currently being displayed
+ * Output the ID of the author of the activity comment currently being displayed.
  *
  * @since BuddyPress (1.5)
  *
@@ -1649,14 +1896,15 @@ function bp_activity_comment_user_id() {
 }
 
 	/**
-	 * Gets the user_id of the author of the activity comment currently being displayed
+	 * Return the ID of the author of the activity comment currently being displayed.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_activity_comment_user_id' hook
+	 * @uses apply_filters() To call the 'bp_activity_comment_user_id' hook.
 	 *
-	 * @return int|bool $user_id The user_id of the author of the displayed activity comment. False on failure
+	 * @return int|bool $user_id The user_id of the author of the displayed
+	 *         activity comment. False on failure.
 	 */
 	function bp_get_activity_comment_user_id() {
 		global $activities_template;
@@ -1667,7 +1915,7 @@ function bp_activity_comment_user_id() {
 	}
 
 /**
- * Echoes the author link for the activity comment currently being displayed
+ * Output the author link for the activity comment currently being displayed.
  *
  * @since BuddyPress (1.5)
  *
@@ -1678,7 +1926,7 @@ function bp_activity_comment_user_link() {
 }
 
 	/**
-	 * Gets the author link for the activity comment currently being displayed
+	 * Return the author link for the activity comment currently being displayed.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
@@ -1686,7 +1934,7 @@ function bp_activity_comment_user_link() {
 	 * @uses bp_get_activity_comment_user_id()
 	 * @uses apply_filters() To call the 'bp_activity_comment_user_link' hook
 	 *
-	 * @return string $user_link The URL of the activity comment author's profile
+	 * @return string $user_link The URL of the activity comment author's profile.
 	 */
 	function bp_get_activity_comment_user_link() {
 		$user_link = bp_core_get_user_domain( bp_get_activity_comment_user_id() );
@@ -1695,7 +1943,7 @@ function bp_activity_comment_user_link() {
 	}
 
 /**
- * Echoes the author name for the activity comment currently being displayed
+ * Output the author name for the activity comment currently being displayed.
  *
  * @since BuddyPress (1.5)
  *
@@ -1706,17 +1954,18 @@ function bp_activity_comment_name() {
 }
 
 	/**
-	 * Gets the author name for the activity comment currently being displayed
+	 * Return the author name for the activity comment currently being displayed.
 	 *
-	 * The use of the bp_acomment_name filter is deprecated. Please use bp_activity_comment_name
+	 * The use of the 'bp_acomment_name' filter is deprecated. Please use
+	 * 'bp_activity_comment_name'.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_acomment_name' hook
-	 * @uses apply_filters() To call the 'bp_activity_comment_name' hook
+	 * @uses apply_filters() To call the 'bp_acomment_name' hook.
+	 * @uses apply_filters() To call the 'bp_activity_comment_name' hook.
 	 *
-	 * @return string $name The full name of the activity comment author
+	 * @return string $name The full name of the activity comment author.
 	 */
 	function bp_get_activity_comment_name() {
 		global $activities_template;
@@ -1730,7 +1979,7 @@ function bp_activity_comment_name() {
 	}
 
 /**
- * Echoes the date_recorded of the activity comment currently being displayed
+ * Output the date_recorded of the activity comment currently being displayed.
  *
  * @since BuddyPress (1.5)
  *
@@ -1741,7 +1990,7 @@ function bp_activity_comment_date_recorded() {
 }
 
 	/**
-	 * Gets the date_recorded for the activity comment currently being displayed
+	 * Return the date_recorded for the activity comment currently being displayed.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
@@ -1749,7 +1998,8 @@ function bp_activity_comment_date_recorded() {
 	 * @uses bp_core_time_since()
 	 * @uses apply_filters() To call the 'bp_activity_comment_date_recorded' hook
 	 *
-	 * @return string|bool $date_recorded Time since the activity was recorded, of the form "%s ago". False on failure
+	 * @return string|bool $date_recorded Time since the activity was recorded,
+	 *         in the form "%s ago". False on failure.
 	 */
 	function bp_get_activity_comment_date_recorded() {
 		global $activities_template;
@@ -1763,7 +2013,7 @@ function bp_activity_comment_date_recorded() {
 	}
 
 /**
- * Echoes the 'delete' URL for the activity comment currently being displayed
+ * Output the 'delete' URL for the activity comment currently being displayed.
  *
  * @since BuddyPress (1.5)
  *
@@ -1782,9 +2032,10 @@ function bp_activity_comment_delete_link() {
 	 * @uses bp_get_root_domain()
 	 * @uses bp_get_activity_slug()
 	 * @uses bp_get_activity_comment_id()
-	 * @uses apply_filters() To call the 'bp_activity_comment_delete_link' hook
+	 * @uses apply_filters() To call the 'bp_activity_comment_delete_link' hook.
 	 *
-	 * @return string $link The nonced URL for deleting the current activity comment
+	 * @return string $link The nonced URL for deleting the current
+	 *         activity comment.
 	 */
 	function bp_get_activity_comment_delete_link() {
 		$link = wp_nonce_url( bp_get_root_domain() . '/' . bp_get_activity_slug() . '/delete/' . bp_get_activity_comment_id() . '?cid=' . bp_get_activity_comment_id(), 'bp_activity_delete_link' );
@@ -1793,7 +2044,7 @@ function bp_activity_comment_delete_link() {
 	}
 
 /**
- * Echoes the content of the activity comment currently being displayed
+ * Output the content of the activity comment currently being displayed.
  *
  * @since BuddyPress (1.5)
  *
@@ -1804,19 +2055,20 @@ function bp_activity_comment_content() {
 }
 
 	/**
-	 * Gets the content of the activity comment currently being displayed
+	 * Return the content of the activity comment currently being displayed.
 	 *
-	 * The content is run through two filters. bp_get_activity_content will apply all filters
-	 * applied to activity items in general. Use bp_activity_comment_content to modify the
-	 * content of activity comments only.
+	 * The content is run through two filters. 'bp_get_activity_content'
+	 * will apply all filters applied to activity items in general. Use
+	 * 'bp_activity_comment_content' to modify the content of activity
+	 * comments only.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_content' hook
-	 * @uses apply_filters() To call the 'bp_activity_comment_content' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_content' hook.
+	 * @uses apply_filters() To call the 'bp_activity_comment_content' hook.
 	 *
-	 * @return string $content The content of the current activity comment
+	 * @return string $content The content of the current activity comment.
 	 */
 	function bp_get_activity_comment_content() {
 		global $activities_template;
@@ -1827,7 +2079,7 @@ function bp_activity_comment_content() {
 	}
 
 /**
- * Echoes the activity comment count
+ * Output the activity comment count.
  *
  * @since BuddyPress (1.2)
  *
@@ -1838,21 +2090,22 @@ function bp_activity_comment_count() {
 }
 
 	/**
-	 * Gets the content of the activity comment currently being displayed
+	 * Return the content of the activity comment currently being displayed.
 	 *
-	 * The content is run through two filters. bp_get_activity_content will apply all filters
-	 * applied to activity items in general. Use bp_activity_comment_content to modify the
-	 * content of activity comments only.
+	 * The content is run through two filters. 'bp_get_activity_content'
+	 * will apply all filters applied to activity items in general. Use
+	 * 'bp_activity_comment_content' to modify the content of activity
+	 * comments only.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @todo deprecate $args
-	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 * @uses bp_activity_recurse_comment_count()
-	 * @uses apply_filters() To call the 'bp_activity_get_comment_count' hook
+	 * @uses apply_filters() To call the 'bp_activity_get_comment_count' hook.
+	 * @todo deprecate $args
 	 *
-	 * @return int $count The activity comment count. Defaults to zero
+	 * @param array $args Deprecated.
+	 * @return int $count The activity comment count.
 	 */
 	function bp_activity_get_comment_count( $args = '' ) {
 		global $activities_template;
@@ -1866,21 +2119,21 @@ function bp_activity_comment_count() {
 	}
 
 		/**
-		 * Gets the content of the activity comment currently being displayed
+		 * Return the content of the activity comment currently being displayed.
 		 *
-		 * The content is run through two filters. bp_get_activity_content will apply all filters
-		 * applied to activity items in general. Use bp_activity_comment_content to modify the
-		 * content of activity comments only.
+		 * The content is run through two filters. 'bp_get_activity_content'
+		 * will apply all filters applied to activity items in general.
+		 * Use bp_activity_comment_content to modify the content of
+		 * activity comments only.
 		 *
 		 * @since BuddyPress (1.2)
 		 *
-		 * @todo investigate why bp_activity_recurse_comment_count() is used while being declared
-		 *
-		 * @param object $comment Activity comments object
-		 *
 		 * @uses bp_activity_recurse_comment_count()
 		 * @uses apply_filters() To call the 'bp_activity_get_comment_count' hook
+		 * @todo investigate why bp_activity_recurse_comment_count() is used while being declared
 		 *
+		 * @param object $comment Activity comment object.
+		 * @param int $count The current iteration count.
 		 * @return int $count The activity comment count.
 		 */
 		function bp_activity_recurse_comment_count( $comment, $count = 0 ) {
@@ -1897,7 +2150,27 @@ function bp_activity_comment_count() {
 		}
 
 /**
- * Echoes the activity comment link
+ * Output the depth of the current activity comment.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_activity_comment_depth() {
+	echo bp_activity_get_comment_depth();
+}
+	/**
+	 * Return the current activity comment depth.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @return int
+	 */
+	function bp_activity_get_comment_depth() {
+		global $activities_template;
+		return apply_filters( 'bp_activity_get_comment_depth', $activities_template->activity->current_comment->depth );
+	}
+
+/**
+ * Output the activity comment link.
  *
  * @since BuddyPress (1.2)
  *
@@ -1908,14 +2181,14 @@ function bp_activity_comment_link() {
 }
 
 	/**
-	 * Gets the activity comment link
+	 * Return the activity comment link.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_comment_link' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_comment_link' hook.
 	 *
-	 * @return string The activity comment link
+	 * @return string The activity comment link.
 	 */
 	function bp_get_activity_comment_link() {
 		global $activities_template;
@@ -1923,7 +2196,7 @@ function bp_activity_comment_link() {
 	}
 
 /**
- * Echoes the activity comment form no javascript display CSS
+ * Output the activity comment form no javascript display CSS.
  *
  * @since BuddyPress (1.2)
  *
@@ -1934,13 +2207,14 @@ function bp_activity_comment_form_nojs_display() {
 }
 
 	/**
-	 * Gets the activity comment form no javascript display CSS
+	 * Return the activity comment form no javascript display CSS.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 *
-	 * @return string|bool The activity comment form no javascript display CSS. False on failure
+	 * @return string|bool The activity comment form no javascript
+	 *         display CSS. False on failure
 	 */
 	function bp_get_activity_comment_form_nojs_display() {
 		global $activities_template;
@@ -1951,7 +2225,7 @@ function bp_activity_comment_form_nojs_display() {
 	}
 
 /**
- * Echoes the activity comment form action
+ * Output the activity comment form action.
  *
  * @since BuddyPress (1.2)
  *
@@ -1962,22 +2236,22 @@ function bp_activity_comment_form_action() {
 }
 
 	/**
-	 * Gets the activity comment form action
+	 * Return the activity comment form action.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @uses home_url()
 	 * @uses bp_get_activity_root_slug()
-	 * @uses apply_filters() To call the 'bp_get_activity_comment_form_action' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_comment_form_action' hook.
 	 *
-	 * @return string The activity comment form action
+	 * @return string The activity comment form action.
 	 */
 	function bp_get_activity_comment_form_action() {
 		return apply_filters( 'bp_get_activity_comment_form_action', home_url( bp_get_activity_root_slug() . '/reply/' ) );
 	}
 
 /**
- * Echoes the activity permalink id
+ * Output the activity permalink ID.
  *
  * @since BuddyPress (1.2)
  *
@@ -1988,20 +2262,20 @@ function bp_activity_permalink_id() {
 }
 
 	/**
-	 * Gets the activity permalink id
+	 * Return the activity permalink ID.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @uses apply_filters() To call the 'bp_get_activity_permalink_id' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_permalink_id' hook.
 	 *
-	 * @return string The activity permalink id
+	 * @return string The activity permalink ID.
 	 */
 	function bp_get_activity_permalink_id() {
 		return apply_filters( 'bp_get_activity_permalink_id', bp_current_action() );
 	}
 
 /**
- * Echoes the activity thread permalink
+ * Output the activity thread permalink.
  *
  * @since BuddyPress (1.2)
  *
@@ -2012,14 +2286,14 @@ function bp_activity_thread_permalink() {
 }
 
 	/**
-	 * Gets the activity thread permalink
+	 * Return the activity thread permalink.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @uses bp_activity_get_permalink()
-	 * @uses apply_filters() To call the 'bp_get_activity_thread_permalink' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_thread_permalink' hook.
 	 *
-	 * @return string $link The activity thread permalink
+	 * @return string $link The activity thread permalink.
 	 */
 	function bp_get_activity_thread_permalink() {
 		global $activities_template;
@@ -2030,7 +2304,7 @@ function bp_activity_thread_permalink() {
 	}
 
 /**
- * Echoes the activity comment permalink
+ * Output the activity comment permalink.
  *
  * @since BuddyPress (1.8)
  *
@@ -2040,14 +2314,14 @@ function bp_activity_comment_permalink() {
 	echo bp_get_activity_comment_permalink();
 }
 	/**
-	 * Gets the activity comment permalink
+	 * Return the activity comment permalink.
 	 *
 	 * @since BuddyPress (1.8)
 	 *
 	 * @uses bp_activity_get_permalink()
-	 * @uses apply_filters() To call the 'bp_get_activity_comment_permalink' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_comment_permalink' hook.
 	 *
-	 * @return string $link The activity comment permalink
+	 * @return string $link The activity comment permalink.
 	 */
 	function bp_get_activity_comment_permalink() {
 		global $activities_template;
@@ -2058,7 +2332,7 @@ function bp_activity_comment_permalink() {
 	}
 
 /**
- * Echoes the activity favorite link
+ * Output the activity favorite link.
  *
  * @since BuddyPress (1.2)
  *
@@ -2069,7 +2343,7 @@ function bp_activity_favorite_link() {
 }
 
 	/**
-	 * Gets the activity favorite link
+	 * Return the activity favorite link.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
@@ -2079,7 +2353,7 @@ function bp_activity_favorite_link() {
 	 * @uses bp_get_activity_root_slug()
 	 * @uses apply_filters() To call the 'bp_get_activity_favorite_link' hook
 	 *
-	 * @return string The activity favorite link
+	 * @return string The activity favorite link.
 	 */
 	function bp_get_activity_favorite_link() {
 		global $activities_template;
@@ -2087,7 +2361,7 @@ function bp_activity_favorite_link() {
 	}
 
 /**
- * Echoes the activity unfavorite link
+ * Output the activity unfavorite link.
  *
  * @since BuddyPress (1.2)
  *
@@ -2098,7 +2372,7 @@ function bp_activity_unfavorite_link() {
 }
 
 	/**
-	 * Gets the activity unfavorite link
+	 * Return the activity unfavorite link.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
@@ -2106,9 +2380,9 @@ function bp_activity_unfavorite_link() {
 	 * @uses wp_nonce_url()
 	 * @uses home_url()
 	 * @uses bp_get_activity_root_slug()
-	 * @uses apply_filters() To call the 'bp_get_activity_unfavorite_link' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_unfavorite_link' hook.
 	 *
-	 * @return string The activity unfavorite link
+	 * @return string The activity unfavorite link.
 	 */
 	function bp_get_activity_unfavorite_link() {
 		global $activities_template;
@@ -2116,7 +2390,7 @@ function bp_activity_unfavorite_link() {
 	}
 
 /**
- * Echoes the activity CSS class
+ * Output the activity CSS class.
  *
  * @since BuddyPress (1.0)
  *
@@ -2127,17 +2401,17 @@ function bp_activity_css_class() {
 }
 
 	/**
-	 * Gets the activity CSS class
+	 * Return the current activity item's CSS class.
 	 *
 	 * @since BuddyPress (1.0)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_activity_mini_activity_types' hook
+	 * @uses apply_filters() To call the 'bp_activity_mini_activity_types' hook.
 	 * @uses bp_activity_get_comment_count()
 	 * @uses bp_activity_can_comment()
-	 * @uses apply_filters() To call the 'bp_get_activity_css_class' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_css_class' hook.
 	 *
-	 * @return string The activity css class
+	 * @return string The activity item's CSS class.
 	 */
 	function bp_get_activity_css_class() {
 		global $activities_template;
@@ -2163,7 +2437,7 @@ function bp_activity_css_class() {
 	}
 
 /**
- * Display the activity delete link.
+ * Output the activity delete link.
  *
  * @since BuddyPress (1.1)
  *
@@ -2186,9 +2460,10 @@ function bp_activity_delete_link() {
 	 * @uses add_query_arg()
 	 * @uses wp_get_referer()
 	 * @uses wp_nonce_url()
-	 * @uses apply_filters() To call the 'bp_get_activity_delete_link' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_delete_link' hook.
 	 *
-	 * @return string $link Activity delete link. Contains $redirect_to arg if on single activity page.
+	 * @return string $link Activity delete link. Contains $redirect_to arg
+	 *         if on single activity page.
 	 */
 	function bp_get_activity_delete_link() {
 		global $activities_template;
@@ -2207,13 +2482,14 @@ function bp_activity_delete_link() {
 	}
 
 /**
- * Display the activity latest update link.
+ * Output the activity latest update link.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $user_id Defaults to 0
- *
+ * @see bp_get_activity_latest_update() for description of parameters.
  * @uses bp_get_activity_latest_update()
+ *
+ * @param int $user_id See {@link bp_get_activity_latest_update()} for description.
  */
 function bp_activity_latest_update( $user_id = 0 ) {
 	echo bp_get_activity_latest_update( $user_id );
@@ -2224,8 +2500,6 @@ function bp_activity_latest_update( $user_id = 0 ) {
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @param int $user_id Defaults to 0
-	 *
 	 * @uses bp_is_user_inactive()
 	 * @uses bp_core_is_user_deleted()
 	 * @uses bp_get_user_meta()
@@ -2235,7 +2509,9 @@ function bp_activity_latest_update( $user_id = 0 ) {
 	 * @uses bp_get_activity_root_slug()
 	 * @uses apply_filters() To call the 'bp_get_activity_latest_update' hook
 	 *
-	 * @return string|bool $latest_update The activity latest update link. False on failure
+	 * @param int $user_id If empty, will fall back on displayed user.
+	 * @return string|bool $latest_update The activity latest update link.
+	 *         False on failure
 	 */
 	function bp_get_activity_latest_update( $user_id = 0 ) {
 
@@ -2255,13 +2531,14 @@ function bp_activity_latest_update( $user_id = 0 ) {
 	}
 
 /**
- * Display the activity filter links.
+ * Output the activity filter links.
  *
  * @since BuddyPress (1.1)
  *
- * @param array $args Defaults to false
- *
+ * @see bp_get_activity_filter_links() for description of parameters.
  * @uses bp_get_activity_filter_links()
+ *
+ * @param array $args See {@link bp_get_activity_filter_links()} for description.
  */
 function bp_activity_filter_links( $args = false ) {
 	echo bp_get_activity_filter_links( $args );
@@ -2272,17 +2549,20 @@ function bp_activity_filter_links( $args = false ) {
 	 *
 	 * @since BuddyPress (1.1)
 	 *
-	 * @param array $args Defaults to false
-	 *
 	 * @uses wp_parse_args()
 	 * @uses BP_Activity_Activity::get_recorded_components() {@link BP_Activity_Activity}
 	 * @uses esc_attr()
 	 * @uses add_query_arg()
 	 * @uses remove_query_arg()
-	 * @uses apply_filters() To call the 'bp_get_activity_filter_link_href' hook
-	 * @uses apply_filters() To call the 'bp_get_activity_filter_links' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_filter_link_href' hook.
+	 * @uses apply_filters() To call the 'bp_get_activity_filter_links' hook.
 	 *
-	 * @return string|bool $component_links The activity filter links. False on failure
+	 * @param array $args {
+	 *     @type string $style The type of markup to use for the links.
+	 *           'list', 'paragraph', or 'span'. Default: 'list'.
+	 * }
+	 * @return string|bool $component_links The activity filter links.
+	 *         False on failure.
 	 */
 	function bp_get_activity_filter_links( $args = false ) {
 
@@ -2349,15 +2629,15 @@ function bp_activity_filter_links( $args = false ) {
 	}
 
 /**
- * Determine if a comment can be made on an activity item
+ * Determine if a comment can be made on an activity item.
  *
  * @since BuddyPress (1.2)
  *
  * @global object $activities_template {@link BP_Activity_Template}
  * @uses bp_get_activity_action_name()
- * @uses apply_filters() To call the 'bp_activity_can_comment' hook
+ * @uses apply_filters() To call the 'bp_activity_can_comment' hook.
  *
- * @return bool $can_comment Defaults to true
+ * @return bool $can_comment True if item can receive comments.
  */
 function bp_activity_can_comment() {
 	global $activities_template;
@@ -2376,30 +2656,37 @@ function bp_activity_can_comment() {
 }
 
 /**
- * Determine if a comment can be made on an activity reply item
+ * Determine if a comment can be made on an activity reply item.
  *
- * @since BuddyPress (1.5)
+ * Defaults to true, but can be modified by plugins.
  *
- * @param object $comment Activity comment
+ * @since BuddyPress (1.5)
  *
  * @uses apply_filters() To call the 'bp_activity_can_comment_reply' hook
  *
- * @return bool $can_comment Defaults to true
+ * @param object $comment Activity comment.
+ * @return bool $can_comment True if comment can receive comments.
  */
 function bp_activity_can_comment_reply( $comment ) {
 	$can_comment = true;
 
+	if ( get_option( 'thread_comments' ) && bp_activity_get_comment_depth() >= get_option( 'thread_comments_depth' ) ) {
+		$can_comment = false;
+	}
+
 	return apply_filters( 'bp_activity_can_comment_reply', $can_comment, $comment );
 }
 
 /**
- * Determine if an favorites are allowed
+ * Determine if an favorites are allowed.
+ *
+ * Defaults to true, but can be modified by plugins.
  *
  * @since BuddyPress (1.5)
  *
- * @uses apply_filters() To call the 'bp_activity_can_favorite' hook
+ * @uses apply_filters() To call the 'bp_activity_can_favorite' hook.
  *
- * @return bool $can_favorite Defaults to true
+ * @return bool $can_favorite True if comment can receive comments.
  */
 function bp_activity_can_favorite() {
 	$can_favorite = true;
@@ -2408,29 +2695,29 @@ function bp_activity_can_favorite() {
 }
 
 /**
- * Echoes the total favorite count for a specified user
+ * Output the total favorite count for a specified user.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $user_id Defaults to 0
- *
+ * @see bp_get_total_favorite_count_for_user() for description of parameters.
  * @uses bp_get_total_favorite_count_for_user()
+ *
+ * @param int $user_id See {@link bp_get_total_favorite_count_for_user()}.
  */
 function bp_total_favorite_count_for_user( $user_id = 0 ) {
 	echo bp_get_total_favorite_count_for_user( $user_id );
 }
 
 	/**
-	 * Returns the total favorite count for a specified user
+	 * Return the total favorite count for a specified user.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @param int $user_id Defaults to 0
-	 *
 	 * @uses bp_activity_total_favorites_for_user()
 	 * @uses apply_filters() To call the 'bp_get_total_favorite_count_for_user' hook
 	 *
-	 * @return int The total favorite count for a specified user
+	 * @param int $user_id ID of user being queried. Default: displayed user ID.
+	 * @return int The total favorite count for the specified user.
 	 */
 	function bp_get_total_favorite_count_for_user( $user_id = 0 ) {
 		if ( ! $user_id ) {
@@ -2439,29 +2726,32 @@ function bp_total_favorite_count_for_user( $user_id = 0 ) {
 
 		return apply_filters( 'bp_get_total_favorite_count_for_user', bp_activity_total_favorites_for_user( $user_id ) );
 	}
+	add_filter( 'bp_get_total_favorite_count_for_user', 'bp_core_number_format' );
 
 /**
- * Echoes the total mention count for a specified user
+ * Output the total mention count for a specified user.
  *
  * @since BuddyPress (1.2)
  *
- * @param int $user_id Defaults to 0
- *
+ * @see bp_get_total_mention_count_for_user() for description of parameters.
  * @uses bp_get_total_favorite_count_for_user()
+ *
+ * @param int $user_id See {@link bp_get_total_mention_count_for_user()}.
  */
 function bp_total_mention_count_for_user( $user_id = 0 ) {
 	echo bp_get_total_mention_count_for_user( $user_id );
 }
 
 	/**
-	 * Returns the total mention count for a specified user
+	 * Return the total mention count for a specified user.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @param int $user_id Defaults to 0
 	 * @uses bp_get_user_meta()
-	 * @uses apply_filters() To call the 'bp_get_total_mention_count_for_user' hook
-	 * @return int The total mention count for a specified user
+	 * @uses apply_filters() To call the 'bp_get_total_mention_count_for_user' hook.
+	 *
+	 * @param int $user_id ID of user being queried. Default: displayed user ID.
+	 * @return int The total mention count for the specified user.
 	 */
 	function bp_get_total_mention_count_for_user( $user_id = 0 ) {
 		if ( ! $user_id ) {
@@ -2470,9 +2760,10 @@ function bp_total_mention_count_for_user( $user_id = 0 ) {
 
 		return apply_filters( 'bp_get_total_mention_count_for_user', bp_get_user_meta( $user_id, 'bp_new_mention_count', true ) );
 	}
+	add_filter( 'bp_get_total_mention_count_for_user', 'bp_core_number_format' );
 
 /**
- * Echoes the public message link for displayed user
+ * Output the public message link for displayed user.
  *
  * @since BuddyPress (1.2)
  *
@@ -2483,38 +2774,63 @@ function bp_send_public_message_link() {
 }
 
 	/**
-	 * Returns the public message link for displayed user
+	 * Return the public message link for the displayed user.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @global object $bp BuddyPress global settings
-	 * @uses bp_is_my_profile()
 	 * @uses is_user_logged_in()
+	 * @uses bp_is_my_profile()
+	 * @uses bp_is_user()
 	 * @uses wp_nonce_url()
-	 * @uses bp_loggedin_user_domain()
-	 * @uses bp_get_activity_slug()
-	 * @uses bp_core_get_username()
+	 * @uses bp_get_activity_directory_permalink()
 	 * @uses apply_filters() To call the 'bp_get_send_public_message_link' hook
 	 *
-	 * @return string The public message link for displayed user
+	 * @return string The public message link for the displayed user.
 	 */
 	function bp_get_send_public_message_link() {
-		global $bp;
 
-		if ( bp_is_my_profile() || !is_user_logged_in() )
+		if ( ! is_user_logged_in() || ! bp_is_user() || bp_is_my_profile() )
 			return false;
 
-		return apply_filters( 'bp_get_send_public_message_link', wp_nonce_url( bp_get_activity_directory_permalink() . '?r=' . bp_core_get_username( bp_displayed_user_id(), bp_get_displayed_user_username(), $bp->displayed_user->userdata->user_login ) ) );
+		return apply_filters( 'bp_get_send_public_message_link', wp_nonce_url( bp_get_activity_directory_permalink() . '?r=' . bp_get_displayed_user_mentionname() ) );
 	}
 
 /**
- * Echoes the mentioned user display name
+ * Recurse through all activity comments and return the activity comment IDs.
  *
- * @since BuddyPress (1.2)
+ * @since BuddyPress (2.0.0)
  *
- * @param int|string User id or username
+ * @param array $activity Array of activities generated from {@link bp_activity_get()}.
+ * @param array $activity_ids Used for recursion purposes in this function.
+ * @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 mentioned user display name.
+ *
+ * @since BuddyPress (1.2)
  *
+ * @see bp_get_mentioned_user_display_name() for description of parameters.
  * @uses bp_get_mentioned_user_display_name()
+ *
+ * @param int|string $user_id_or_username See {@link bp_get_mentioned_user_display_name()}.
  */
 function bp_mentioned_user_display_name( $user_id_or_username ) {
 	echo bp_get_mentioned_user_display_name( $user_id_or_username );
@@ -2525,12 +2841,11 @@ function bp_mentioned_user_display_name( $user_id_or_username ) {
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @param int|string User id or username
-	 *
 	 * @uses bp_core_get_user_displayname()
-	 * @uses apply_filters() To call the 'bp_get_mentioned_user_display_name' hook
+	 * @uses apply_filters() To call the 'bp_get_mentioned_user_display_name' hook.
 	 *
-	 * @return string The mentioned user display name
+	 * @param int|string User ID or username.
+	 * @return string The mentioned user's display name.
 	 */
 	function bp_get_mentioned_user_display_name( $user_id_or_username ) {
 		if ( !$name = bp_core_get_user_displayname( $user_id_or_username ) )
@@ -2540,31 +2855,45 @@ function bp_mentioned_user_display_name( $user_id_or_username ) {
 	}
 
 /**
- * Output button for sending a public message
+ * Output button for sending a public message (an @-mention).
  *
  * @since BuddyPress (1.2)
  *
- * @param array $args Optional
- *
+ * @see bp_get_send_public_message_button() for description of parameters.
  * @uses bp_get_send_public_message_button()
+ *
+ * @param array $args See {@link bp_get_send_public_message_button()}.
  */
 function bp_send_public_message_button( $args = '' ) {
 	echo bp_get_send_public_message_button( $args );
 }
 
 	/**
-	 * Return button for sending a public message
+	 * Return button for sending a public message (an @-mention).
 	 *
 	 * @since BuddyPress (1.2)
 	 *
-	 * @param array $args Optional
-	 *
 	 * @uses bp_get_send_public_message_link()
 	 * @uses wp_parse_args()
 	 * @uses bp_get_button()
-	 * @uses apply_filters() To call the 'bp_get_send_public_message_button' hook
-	 *
-	 * @return string The button for sending a public message
+	 * @uses apply_filters() To call the 'bp_get_send_public_message_button' hook.
+	 *
+	 * @param array $args {
+	 *     All arguments are optional. See {@link BP_Button} for complete
+	 *     descriptions.
+	 *     @type string $id Default: 'public_message'.
+	 *     @type string $component Default: 'activity'.
+	 *     @type bool $must_be_logged_in Default: true.
+	 *     @type bool $block_self Default: true.
+	 *     @type string $wrapper_id Default: 'post-mention'.
+	 *     @type string $link_href Default: the public message link for
+	 *           the current member in the loop.
+	 *     @type string $link_title Default: 'Send a public message on your
+	 *           activity stream.'.
+	 *     @type string $link_text Default: 'Public Message'.
+	 *     @type string $link_class Default: 'activity-button mention'.
+	 * }
+	 * @return string The button for sending a public message.
 	 */
 	function bp_get_send_public_message_button( $args = '' ) {
 		$defaults = array(
@@ -2586,7 +2915,7 @@ function bp_send_public_message_button( $args = '' ) {
 	}
 
 /**
- * Outputs the activity post form action
+ * Output the activity post form action.
  *
  * @since BuddyPress (1.2)
  *
@@ -2597,27 +2926,33 @@ function bp_activity_post_form_action() {
 }
 
 	/**
-	 * Returns the activity post form action
+	 * Return the activity post form action.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @uses home_url()
 	 * @uses bp_get_activity_root_slug()
-	 * @uses apply_filters() To call the 'bp_get_activity_post_form_action' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_post_form_action' hook.
 	 *
-	 * @return string The activity post form action
+	 * @return string The activity post form action.
 	 */
 	function bp_get_activity_post_form_action() {
 		return apply_filters( 'bp_get_activity_post_form_action', home_url( bp_get_activity_root_slug() . '/post/' ) );
 	}
 
 /**
- * Looks at all the activity comments on the current activity item, and prints the comments' authors's avatar wrapped in <LI> tags.
+ * Echo a list of linked avatars of users who have commented on the current activity item.
  *
  * Use this function to easily output activity comment authors' avatars.
  *
- * @param array $args See {@link bp_core_fetch_avatar} for accepted values
+ * Avatars are wrapped in <li> elements, but you've got to provide your own
+ * <ul> or <ol> wrapper markup.
+ *
  * @since BuddyPress (1.7)
+ *
+ * @see bp_core_fetch_avatar() for a description of arguments.
+ *
+ * @param array $args See {@link bp_core_fetch_avatar()}.
  */
 function bp_activity_comments_user_avatars( $args = array() ) {
 	$defaults = array(
@@ -2645,10 +2980,11 @@ function bp_activity_comments_user_avatars( $args = array() ) {
 }
 
 /**
- * Returns the user IDs of everyone who's written an activity comment on the current activity item.
+ * Return the IDs of every user who's left a comment on the current activity item.
  *
- * @return bool|array Returns false if there is no current activity items
  * @since BuddyPress (1.7)
+ *
+ * @return bool|array An array of IDs, or false if none are found.
  */
 function bp_activity_get_comments_user_ids() {
 	if ( empty( $GLOBALS['activities_template']->activity ) || empty( $GLOBALS['activities_template']->activity->children ) )
@@ -2661,9 +2997,10 @@ function bp_activity_get_comments_user_ids() {
 	/**
 	 * Recurse through all activity comments and collect the IDs of the users who wrote them.
 	 *
-	 * @param array $comments Array of {@link BP_Activity_Activity} items
-	 * @return array Array of user IDs
 	 * @since BuddyPress (1.7)
+	 *
+	 * @param array $comments Array of {@link BP_Activity_Activity} items.
+	 * @return array Array of user IDs.
 	 */
 	function bp_activity_recurse_comments_user_ids( array $comments ) {
 		$user_ids = array();
@@ -2683,15 +3020,38 @@ function bp_activity_get_comments_user_ids() {
 		return $user_ids;
 	}
 
+/**
+ * Output the mentionname for the displayed user.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_displayed_user_mentionname() {
+	echo bp_get_displayed_user_mentionname();
+}
+	/**
+	 * Get the mentionname for the displayed user.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string Mentionname for the displayed user, if available.
+	 */
+	function bp_get_displayed_user_mentionname() {
+		return apply_filters( 'bp_get_displayed_user_mentionname', bp_activity_get_user_mentionname( bp_displayed_user_id() ) );
+	}
 
 /**
- * Renders a list of all the registered activity types for use in a <select> element, or as <input type="checkbox">.
+ * Echo a list of all registered activity types for use in dropdowns or checkbox lists.
  *
- * @param string $output Optional. Either 'select' or 'checkbox'. Defaults to select.
- * @param string|array $args Optional extra arguments:
- *  checkbox_name - Used when type=checkbox. Sets the item's name property.
- *  selected      - Array of strings of activity types to mark as selected/checked.
  * @since BuddyPress (1.7)
+ *
+ * @param string $output Optional. Either 'select' or 'checkbox'. Default: 'select'.
+ * @param array $args {
+ *     Optional extra arguments.
+ *     @type string $checkbox_name When returning checkboxes, sets the 'name'
+ *           attribute.
+ *     @type array|string $selected A list of types that should be checked/
+ *           selected.
+ * }
  */
 function bp_activity_types_list( $output = 'select', $args = '' ) {
 	$defaults = array(
@@ -2729,7 +3089,7 @@ function bp_activity_types_list( $output = 'select', $args = '' ) {
 /* RSS Feed Template Tags ****************************************************/
 
 /**
- * Outputs the sitewide activity feed link
+ * Output the sitewide activity feed link.
  *
  * @since BuddyPress (1.0)
  *
@@ -2740,22 +3100,22 @@ function bp_sitewide_activity_feed_link() {
 }
 
 	/**
-	 * Returns the sitewide activity feed link
+	 * Returns the sitewide activity feed link.
 	 *
 	 * @since BuddyPress (1.0)
 	 *
 	 * @uses home_url()
 	 * @uses bp_get_activity_root_slug()
-	 * @uses apply_filters() To call the 'bp_get_sitewide_activity_feed_link' hook
+	 * @uses apply_filters() To call the 'bp_get_sitewide_activity_feed_link' hook.
 	 *
-	 * @return string The sitewide activity feed link
+	 * @return string The sitewide activity feed link.
 	 */
 	function bp_get_sitewide_activity_feed_link() {
 		return apply_filters( 'bp_get_sitewide_activity_feed_link', bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/feed/' );
 	}
 
 /**
- * Outputs the member activity feed link
+ * Output the member activity feed link.
  *
  * @since BuddyPress (1.2)
  *
@@ -2766,19 +3126,19 @@ function bp_member_activity_feed_link() {
 }
 
 /**
- * Outputs the member activity feed link
+ * Output the member activity feed link.
  *
  * @since BuddyPress (1.0)
  * @deprecated BuddyPress (1.2)
  *
- * @todo properly deprecated in favor of bp_member_activity_feed_link()
+ * @todo properly deprecate in favor of bp_member_activity_feed_link().
  *
  * @uses bp_get_member_activity_feed_link()
  */
 function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link(); }
 
 	/**
-	 * Returns the member activity feed link
+	 * Return the member activity feed link.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
@@ -2789,9 +3149,9 @@ function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link
 	 * @uses bp_is_active()
 	 * @uses bp_get_friends_slug()
 	 * @uses bp_get_groups_slug()
-	 * @uses apply_filters() To call the 'bp_get_activities_member_rss_link' hook
+	 * @uses apply_filters() To call the 'bp_get_activities_member_rss_link' hook.
 	 *
-	 * @return string $link The member activity feed link
+	 * @return string $link The member activity feed link.
 	 */
 	function bp_get_member_activity_feed_link() {
 
@@ -2812,16 +3172,16 @@ function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link
 	}
 
 	/**
-	 * Returns the member activity feed link
+	 * Return the member activity feed link.
 	 *
 	 * @since BuddyPress (1.0)
 	 * @deprecated BuddyPress (1.2)
 	 *
-	 * @todo properly deprecated in favor of bp_get_member_activity_feed_link()
+	 * @todo properly deprecate in favor of bp_get_member_activity_feed_link().
 	 *
 	 * @uses bp_get_member_activity_feed_link()
 	 *
-	 * @return string The member activity feed link
+	 * @return string The member activity feed link.
 	 */
 	function bp_get_activities_member_rss_link() { return bp_get_member_activity_feed_link(); }
 
@@ -2829,7 +3189,7 @@ function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link
 /** Template tags for RSS feed output ****************************************/
 
 /**
- * Outputs the activity feed item guid
+ * Outputs the activity feed item guid.
  *
  * @since BuddyPress (1.0)
  *
@@ -2840,14 +3200,14 @@ function bp_activity_feed_item_guid() {
 }
 
 	/**
-	 * Returns the activity feed item guid
+	 * Returns the activity feed item guid.
 	 *
 	 * @since BuddyPress (1.2)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_guid' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_guid' hook.
 	 *
-	 * @return string The activity feed item guid
+	 * @return string The activity feed item guid.
 	 */
 	function bp_get_activity_feed_item_guid() {
 		global $activities_template;
@@ -2856,7 +3216,7 @@ function bp_activity_feed_item_guid() {
 	}
 
 /**
- * Outputs the activity feed item title
+ * Output the activity feed item title.
  *
  * @since BuddyPress (1.0)
  *
@@ -2867,7 +3227,7 @@ function bp_activity_feed_item_title() {
 }
 
 	/**
-	 * Returns the activity feed item title
+	 * Return the activity feed item title.
 	 *
 	 * @since BuddyPress (1.0)
 	 *
@@ -2875,9 +3235,9 @@ function bp_activity_feed_item_title() {
 	 * @uses ent2ncr()
 	 * @uses convert_chars()
 	 * @uses bp_create_excerpt()
-	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_title' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_title' hook.
 	 *
-	 * @return string $title The activity feed item title
+	 * @return string $title The activity feed item title.
 	 */
 	function bp_get_activity_feed_item_title() {
 		global $activities_template;
@@ -2900,7 +3260,7 @@ function bp_activity_feed_item_title() {
 	}
 
 /**
- * Outputs the activity feed item link
+ * Output the activity feed item link
  *
  * @since BuddyPress (1.0)
  *
@@ -2911,14 +3271,14 @@ function bp_activity_feed_item_link() {
 }
 
 	/**
-	 * Returns the activity feed item link
+	 * Return the activity feed item link
 	 *
 	 * @since BuddyPress (1.0)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_link' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_link' hook.
 	 *
-	 * @return string The activity feed item link
+	 * @return string The activity feed item link.
 	 */
 	function bp_get_activity_feed_item_link() {
 		global $activities_template;
@@ -2927,7 +3287,7 @@ function bp_activity_feed_item_link() {
 	}
 
 /**
- * Outputs the activity feed item date
+ * Output the activity feed item date.
  *
  * @since BuddyPress (1.0)
  *
@@ -2938,14 +3298,14 @@ function bp_activity_feed_item_date() {
 }
 
 	/**
-	 * Returns the activity feed item date
+	 * Return the activity feed item date.
 	 *
 	 * @since BuddyPress (1.0)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
-	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_date' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_date' hook.
 	 *
-	 * @return string The activity feed item date
+	 * @return string The activity feed item date.
 	 */
 	function bp_get_activity_feed_item_date() {
 		global $activities_template;
@@ -2954,7 +3314,7 @@ function bp_activity_feed_item_date() {
 	}
 
 /**
- * Outputs the activity feed item description
+ * Output the activity feed item description.
  *
  * @since BuddyPress (1.0)
  *
@@ -2965,16 +3325,16 @@ function bp_activity_feed_item_description() {
 }
 
 	/**
-	 * Returns the activity feed item description
+	 * Return the activity feed item description.
 	 *
 	 * @since BuddyPress (1.0)
 	 *
 	 * @global object $activities_template {@link BP_Activity_Template}
 	 * @uses ent2ncr()
 	 * @uses convert_chars()
-	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_description' hook
+	 * @uses apply_filters() To call the 'bp_get_activity_feed_item_description' hook.
 	 *
-	 * @return string The activity feed item description
+	 * @return string The activity feed item description.
 	 */
 	function bp_get_activity_feed_item_description() {
 		global $activities_template;
@@ -2987,7 +3347,7 @@ function bp_activity_feed_item_description() {
 	}
 
 /**
- * Template tag so we can hook activity feed to <head>
+ * Template tag so we can hook activity feed to <head>.
  *
  * @since BuddyPress (1.5)
  *
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-actions.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-actions.php
index d259864998de23293fcfc12a9897a7331f4c22d1..e53909059c854fba09b941f7d7700c58bbdc95cd 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-actions.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-actions.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Blogs Actions
+ * BuddyPress Blogs Actions.
  *
  * @package BuddyPress
  * @subpackage BlogsActions
@@ -11,11 +11,9 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Redirect to a random blog in the multisite network
+ * Redirect to a random blog in the multisite network.
  *
- * @since BuddyPress (1.0)
- * @package BuddyPress
- * @subpackage BlogsActions
+ * @since BuddyPress (1.0.0)
  */
 function bp_blogs_redirect_to_random_blog() {
 
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-activity.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-activity.php
index 490b86e60f2bfaa15e7692fd92609e5963e112b8..7a867fb1beac6e7c87bcf499e0fb12be2ab88dc1 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-activity.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-activity.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Blogs Activity
+ * BuddyPress Blogs Activity.
  *
  * @package BuddyPress
  * @subpackage BlogsActivity
@@ -11,13 +11,13 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Register activity actions for the blogs component
+ * Register activity actions for the blogs component.
  *
- * @since BuddyPress (1.0)
- * @package BuddyPress
- * @subpackage BlogsActivity
- * @global type $bp
- * @return boolean
+ * @since BuddyPress (1.0.0)
+ *
+ * @global object $bp The BuddyPress global settings object.
+ *
+ * @return bool|null Returns false if activity component is not active.
  */
 function bp_blogs_register_activity_actions() {
 	global $bp;
@@ -28,25 +28,237 @@ function bp_blogs_register_activity_actions() {
 	}
 
 	if ( is_multisite() ) {
-		bp_activity_set_action( $bp->blogs->id, 'new_blog', __( 'New site created',        'buddypress' ) );
+		bp_activity_set_action(
+			$bp->blogs->id,
+			'new_blog',
+			__( 'New site created', 'buddypress' ),
+			'bp_blogs_format_activity_action_new_blog'
+		);
 	}
 
-	bp_activity_set_action( $bp->blogs->id, 'new_blog_post',    __( 'New post published',      'buddypress' ) );
-	bp_activity_set_action( $bp->blogs->id, 'new_blog_comment', __( 'New post comment posted', 'buddypress' ) );
+	bp_activity_set_action(
+		$bp->blogs->id,
+		'new_blog_post',
+		__( 'New post published', 'buddypress' ),
+		'bp_blogs_format_activity_action_new_blog_post'
+	);
+
+	bp_activity_set_action(
+		$bp->blogs->id,
+		'new_blog_comment',
+		__( 'New post comment posted', 'buddypress' ),
+		'bp_blogs_format_activity_action_new_blog_comment'
+	);
 
 	do_action( 'bp_blogs_register_activity_actions' );
 }
 add_action( 'bp_register_activity_actions', 'bp_blogs_register_activity_actions' );
 
 /**
- * Record the activity to the actvity stream
+ * Format 'new_blog' activity actions.
  *
- * @since BuddyPress (1.0)
- * @package BuddyPress
- * @subpackage BlogsActivity
- * @global BuddyPress $bp
- * @param array $args
- * @return boolean
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param obj $activity Activity data object.
+ */
+function bp_blogs_format_activity_action_new_blog( $action, $activity ) {
+	$blog_url  = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
+	$blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
+
+	$action = sprintf( __( '%s created the site %s', 'buddypress' ), bp_core_get_userlink( $activity->user_id ), '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' );
+
+	// Legacy filter - requires the BP_Blogs_Blog object
+	if ( has_filter( 'bp_blogs_activity_created_blog_action' ) ) {
+		$user_blog = BP_Blogs_Blog::get_user_blog( $activity->user_id, $activity->item_id );
+		if ( $user_blog ) {
+			$recorded_blog = new BP_Blogs_Blog( $user_blog );
+		}
+
+		if ( isset( $recorded_blog ) ) {
+			$action = apply_filters( 'bp_blogs_activity_created_blog_action', $action, $recorded_blog, $blog_name, bp_blogs_get_blogmeta( $activity->item_id, 'description' ) );
+		}
+	}
+
+	return apply_filters( 'bp_blogs_format_activity_action_new_blog', $action, $activity );
+}
+
+/**
+ * Format 'new_blog_post' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param obj $activity Activity data object.
+ */
+function bp_blogs_format_activity_action_new_blog_post( $action, $activity ) {
+	$blog_url  = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
+	$blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
+
+	if ( empty( $blog_url ) || empty( $blog_name ) ) {
+		$blog_url  = get_home_url( $activity->item_id );
+		$blog_name = get_blog_option( $activity->item_id, 'blogname' );
+
+		bp_blogs_update_blogmeta( $activity->item_id, 'url', $blog_url );
+		bp_blogs_update_blogmeta( $activity->item_id, 'name', $blog_name );
+	}
+
+	$post_url = add_query_arg( 'p', $activity->secondary_item_id, trailingslashit( $blog_url ) );
+
+	$post_title = bp_activity_get_meta( $activity->id, 'post_title' );
+
+	// Should only be empty at the time of post creation
+	if ( empty( $post_title ) ) {
+		switch_to_blog( $activity->item_id );
+
+		$post = get_post( $activity->secondary_item_id );
+		if ( is_a( $post, 'WP_Post' ) ) {
+			$post_title = $post->post_title;
+			bp_activity_update_meta( $activity->id, 'post_title', $post_title );
+		}
+
+		restore_current_blog();
+	}
+
+	$post_link  = '<a href="' . $post_url . '">' . $post_title . '</a>';
+
+	$user_link = bp_core_get_userlink( $activity->user_id );
+
+	if ( is_multisite() ) {
+		$action  = sprintf( __( '%1$s wrote a new post, %2$s, on the site %3$s', 'buddypress' ), $user_link, $post_link, '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' );
+	} else {
+		$action  = sprintf( __( '%1$s wrote a new post, %2$s', 'buddypress' ), $user_link, $post_link );
+	}
+
+	// Legacy filter - requires the post object
+	if ( has_filter( 'bp_blogs_activity_new_post_action' ) ) {
+		switch_to_blog( $activity->item_id );
+		$post = get_post( $activity->secondary_item_id );
+		restore_current_blog();
+
+		if ( ! empty( $post ) && ! is_wp_error( $post ) ) {
+			$action = apply_filters( 'bp_blogs_activity_new_post_action', $action, $post, $post_url );
+		}
+	}
+
+	return apply_filters( 'bp_blogs_format_activity_action_new_blog_post', $action, $activity );
+}
+
+/**
+ * Format 'new_blog_comment' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param obj $activity Activity data object.
+ */
+function bp_blogs_format_activity_action_new_blog_comment( $action, $activity ) {
+	$blog_url  = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
+	$blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
+
+	if ( empty( $blog_url ) || empty( $blog_name ) ) {
+		$blog_url  = get_home_url( $activity->item_id );
+		$blog_name = get_blog_option( $activity->item_id, 'blogname' );
+
+		bp_blogs_update_blogmeta( $activity->item_id, 'url', $blog_url );
+		bp_blogs_update_blogmeta( $activity->item_id, 'name', $blog_name );
+	}
+
+	$post_url   = bp_activity_get_meta( $activity->id, 'post_url' );
+	$post_title = bp_activity_get_meta( $activity->id, 'post_title' );
+
+	// Should only be empty at the time of post creation
+	if ( empty( $post_url ) || empty( $post_title ) ) {
+		switch_to_blog( $activity->item_id );
+
+		$comment = get_comment( $activity->secondary_item_id );
+
+		if ( ! empty( $comment->comment_post_ID ) ) {
+			$post_url = add_query_arg( 'p', $comment->comment_post_ID, trailingslashit( $blog_url ) );
+			bp_activity_update_meta( $activity->id, 'post_url', $post_url );
+
+			$post = get_post( $comment->comment_post_ID );
+
+			if ( is_a( $post, 'WP_Post' ) ) {
+				$post_title = $post->post_title;
+				bp_activity_update_meta( $activity->id, 'post_title', $post_title );
+			}
+		}
+
+		restore_current_blog();
+	}
+
+	$post_link = '<a href="' . $post_url . '">' . $post_title . '</a>';
+	$user_link = bp_core_get_userlink( $activity->user_id );
+
+	if ( is_multisite() ) {
+		$action  = sprintf( __( '%1$s commented on the post, %2$s, on the site %3$s', 'buddypress' ), $user_link, $post_link, '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' );
+	} else {
+		$action  = sprintf( __( '%1$s commented on the post, %2$s', 'buddypress' ), $user_link, $post_link );
+	}
+
+	// Legacy filter - requires the comment object
+	if ( has_filter( 'bp_blogs_activity_new_comment_action' ) ) {
+		switch_to_blog( $activity->item_id );
+		$comment = get_comment( $activity->secondary_item_id );
+		restore_current_blog();
+
+		if ( ! empty( $comment ) && ! is_wp_error( $comment ) ) {
+			$action = apply_filters( 'bp_blogs_activity_new_comment_action', $action, $comment, $post_url . '#' . $activity->secondary_item_id );
+		}
+	}
+
+	return apply_filters( 'bp_blogs_format_activity_action_new_blog_comment', $action, $activity );
+}
+
+/**
+ * Fetch data related to blogs at the beginning of an activity loop.
+ *
+ * This reduces database overhead during the activity loop.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $activities Array of activity items.
+ * @return array
+ */
+function bp_blogs_prefetch_activity_object_data( $activities ) {
+	if ( empty( $activities ) ) {
+		return $activities;
+	}
+
+	$blog_ids = array();
+
+	foreach ( $activities as $activity ) {
+		if ( buddypress()->blogs->id !== $activity->component ) {
+			continue;
+		}
+
+		$blog_ids[] = $activity->item_id;
+	}
+
+	if ( ! empty( $blog_ids ) ) {
+		bp_blogs_update_meta_cache( $blog_ids );
+	}
+
+	return $activities;
+}
+add_filter( 'bp_activity_prefetch_object_data', 'bp_blogs_prefetch_activity_object_data' );
+
+/**
+ * Record blog-related activity to the activity stream.
+ *
+ * @since BuddyPress (1.0.0)
+ *
+ * @see bp_activity_add() for description of parameters.
+ * @global object $bp The BuddyPress global settings object.
+ *
+ * @param array $args {
+ *     See {@link bp_activity_add()} for complete description of arguments.
+ *     The arguments listed here have different default values from
+ *     bp_activity_add().
+ *     @type string $component Default: 'blogs'.
+ * }
+ * @return int|bool On success, returns the activity ID. False on failure.
  */
 function bp_blogs_record_activity( $args = '' ) {
 	global $bp;
@@ -94,13 +306,20 @@ function bp_blogs_record_activity( $args = '' ) {
 }
 
 /**
- * Delete a blogs activity stream item
+ * Delete a blog-related activity stream item.
  *
- * @since BuddyPress (1.0)
- * @package BuddyPress
- * @subpackage BlogsActivity
- * @global BuddyPress $bp
- * @param array $args
+ * @since BuddyPress (1.0.0)
+ *
+ * @see bp_activity_delete() for description of parameters.
+ * @global object $bp The BuddyPress global settings object.
+ *
+ * @param array $args {
+ *     See {@link bp_activity_delete()} for complete description of arguments.
+ *     The arguments listed here have different default values from
+ *     bp_activity_add().
+ *     @type string $component Default: 'blogs'.
+ * }
+ * @return bool True on success, false on failure.
  */
 function bp_blogs_delete_activity( $args = true ) {
 	global $bp;
@@ -128,3 +347,508 @@ function bp_blogs_delete_activity( $args = true ) {
 		'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.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @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' );
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-buddybar.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-buddybar.php
index 5090ecc8c8bbc4391fd3f8ac2ee84264de1e20dd..6d0a49338ea1f2672a671a6dc4906f7543b3b5c7 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-buddybar.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-buddybar.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Blogs Activity
+ * BuddyPress Blogs BuddyBar functions.
  *
  * @package BuddyPress
  * @subpackage BlogsBuddyBar
@@ -11,15 +11,14 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Add a Sites menu to the BuddyBar
+ * Add a Sites menu to the BuddyBar.
  *
- * @since BuddyPress (1.0)
- * @package BuddyPress
- * @subpackage BlogsBuddyBar
- * @global BuddyPress $bp
- * @return boolean
+ * @since BuddyPress (1.0.0)
+ *
+ * @global object $bp The BuddyPress global settings object.
+ *
+ * @return bool|null Returns false on failure. Otherwise echoes the menu item.
  */
-
 function bp_adminbar_blogs_menu() {
 	global $bp;
 
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-cache.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-cache.php
index 64660d15c55b3490f1a67a34508a068570a05e2e..c16fba96fce58b3f797a0aa44db4022b3b8f439c 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-cache.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-cache.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Blogs Caching
+ * BuddyPress Blogs Caching.
  *
  * Caching functions handle the clearing of cached objects and pages on specific
  * actions throughout BuddyPress.
@@ -14,13 +14,33 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Clear the blog object cache
+ * Slurp up blogmeta for a specified set of blogs.
  *
- * @since BuddyPress (1.0)
- * @package BuddyPress
- * @subpackage BlogsCache
- * @param int $blog_id
- * @param int $user_id
+ * It grabs all blogmeta associated with all of the blogs passed
+ * in $blog_ids and adds it to the WP cache. This improves efficiency when
+ * using querying blogmeta inline.
+ *
+ * @param int|str|array $blog_ids Accepts a single blog ID, or a comma-
+ *        separated list or array of blog IDs.
+ */
+function bp_blogs_update_meta_cache( $blog_ids = false ) {
+	$cache_args = array(
+		'object_ids' 	   => $blog_ids,
+		'object_type' 	   => buddypress()->blogs->id,
+		'object_column'    => 'blog_id',
+		'cache_group'      => 'blog_meta',
+		'meta_table' 	   => buddypress()->blogs->table_name_blogmeta,
+	);
+
+	bp_update_meta_cache( $cache_args );
+}
+/**
+ * Clear the blog object cache.
+ *
+ * @since BuddyPress (1.0.0)
+ *
+ * @param int $blog_id ID of the current blog.
+ * @param int $user_id ID of the user whose blog cache should be cleared.
  */
 function bp_blogs_clear_blog_object_cache( $blog_id, $user_id ) {
 	wp_cache_delete( 'bp_blogs_of_user_'        . $user_id, 'bp' );
@@ -28,12 +48,12 @@ function bp_blogs_clear_blog_object_cache( $blog_id, $user_id ) {
 }
 
 /**
- * Clear cache when a new blog is created
+ * Clear cache when a new blog is created.
  *
- * @since BuddyPress (1.0)
- * @package BuddyPress
- * @subpackage BlogsCache
- * @param BP_Blogs_Blog $recorded_blog_obj
+ * @since BuddyPress (1.0.0)
+ *
+ * @param BP_Blogs_Blog $recorded_blog_obj The recorded blog, passed by
+ *        'bp_blogs_new_blog'.
  */
 function bp_blogs_format_clear_blog_cache( $recorded_blog_obj ) {
 	bp_blogs_clear_blog_object_cache( false, $recorded_blog_obj->user_id );
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-classes.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-classes.php
index c030659e4b398f2787570537ac1da0ebc88a0793..956fbb82e7ad8fb016ee6115115ff7c7ea02bd37 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-classes.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-classes.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Blogs Classes
+ * BuddyPress Blogs Classes.
  *
  * @package BuddyPress
  * @subpackage BlogsClasses
@@ -11,25 +11,34 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * The main BuddyPress blog class
+ * The main BuddyPress blog class.
  *
- * @since BuddyPress (1.0)
- * @package BuddyPress
- * @subpackage BlogsClasses
+ * A BP_Blogs_Object represents a link between a specific WordPress blog on a
+ * network and a specific user on that blog.
+ *
+ * @since BuddyPress (1.0.0)
  */
 class BP_Blogs_Blog {
-	var $id;
-	var $user_id;
-	var $blog_id;
-
-	function __construct( $id = null ) {
+	public $id;
+	public $user_id;
+	public $blog_id;
+
+	/**
+	 * Constructor method.
+	 *
+	 * @param int $id Optional. The ID of the blog.
+	 */
+	public function __construct( $id = null ) {
 		if ( !empty( $id ) ) {
 			$this->id = $id;
 			$this->populate();
 		}
 	}
 
-	function populate() {
+	/**
+	 * Populate the object with data about the specific activity item.
+	 */
+	public function populate() {
 		global $wpdb, $bp;
 
 		$blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name} WHERE id = %d", $this->id ) );
@@ -38,7 +47,12 @@ class BP_Blogs_Blog {
 		$this->blog_id = $blog->blog_id;
 	}
 
-	function save() {
+	/**
+	 * Save the BP blog data to the database.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function save() {
 		global $wpdb, $bp;
 
 		$this->user_id = apply_filters( 'bp_blogs_blog_user_id_before_save', $this->user_id, $this->id );
@@ -73,15 +87,41 @@ class BP_Blogs_Blog {
 			return $wpdb->insert_id;
 	}
 
-	function exists() {
+	/**
+	 * Check whether an association between this user and this blog exists.
+	 *
+	 * @return int The number of associations between the user and blog
+	 *         saved in the blog component tables.
+	 */
+	public function exists() {
 		global $bp, $wpdb;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->blogs->table_name} WHERE user_id = %d AND blog_id = %d", $this->user_id, $this->blog_id ) );
 	}
 
-	/* Static Functions */
-
-	function get( $type, $limit = false, $page = false, $user_id = 0, $search_terms = false ) {
+	/** Static Methods ***************************************************/
+
+	/**
+	 * Retrieve a set of blog-user associations.
+	 *
+	 * @param string $type The order in which results should be returned.
+	 *        'active', 'alphabetical', 'newest', or 'random'.
+	 * @param int|bool $limit Optional. The maximum records to return.
+	 *        Default: false.
+	 * @param int|bool $page Optional. The page of records to return.
+	 *        Default: false (unlimited results).
+	 * @param int $user_id Optional. ID of the user whose blogs are being
+	 *        retrieved. Default: 0.
+	 * @param string|bool $search_terms Optional. Search by text stored in
+	 *        blogmeta (such as the blog name). Default: false.
+	 * @param bool $update_meta_cache Whether to pre-fetch metadata for
+	 *        blogs. Default: true.
+	 * @param array $include_blog_ids Array of blog IDs to include.
+	 * @return array Multidimensional results array, structured as follows:
+	 *           'blogs' - Array of located blog objects
+	 *           'total' - A count of the total blogs matching the filter params
+	 */
+	public static function get( $type, $limit = false, $page = false, $user_id = 0, $search_terms = false, $update_meta_cache = true, $include_blog_ids = false ) {
 		global $bp, $wpdb;
 
 		if ( !is_user_logged_in() || ( !bp_current_user_can( 'bp_moderate' ) && ( $user_id != bp_loggedin_user_id() ) ) )
@@ -108,13 +148,20 @@ class BP_Blogs_Blog {
 				break;
 		}
 
+		$include_sql = '';
+		$include_blog_ids = array_filter( wp_parse_id_list( $include_blog_ids ) );
+		if ( ! empty( $include_blog_ids ) ) {
+			$blog_ids_sql = implode( ',', $include_blog_ids );
+			$include_sql  = " AND b.blog_id IN ({$blog_ids_sql})";
+		}
+
 		if ( !empty( $search_terms ) ) {
 			$filter = esc_sql( like_escape( $search_terms ) );
-			$paged_blogs = $wpdb->get_results( "SELECT b.blog_id, b.user_id as admin_user_id, u.user_email as admin_user_email, wb.domain, wb.path, bm.meta_value as last_activity, bm2.meta_value as name FROM {$bp->blogs->table_name} b, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2, {$wpdb->base_prefix}blogs wb, {$wpdb->users} u WHERE b.blog_id = wb.blog_id AND b.user_id = u.ID AND b.blog_id = bm.blog_id AND b.blog_id = bm2.blog_id AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'last_activity' AND bm2.meta_key = 'name' AND bm2.meta_value LIKE '%%$filter%%' {$user_sql} GROUP BY b.blog_id {$order_sql} {$pag_sql}" );
-			$total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2 WHERE b.blog_id = wb.blog_id AND bm.blog_id = b.blog_id AND bm2.blog_id = b.blog_id AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'name' AND bm2.meta_key = 'description' AND ( bm.meta_value LIKE '%%$filter%%' || bm2.meta_value LIKE '%%$filter%%' ) {$user_sql}" );
+			$paged_blogs = $wpdb->get_results( "SELECT b.blog_id, b.user_id as admin_user_id, u.user_email as admin_user_email, wb.domain, wb.path, bm.meta_value as last_activity, bm2.meta_value as name FROM {$bp->blogs->table_name} b, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2, {$wpdb->base_prefix}blogs wb, {$wpdb->users} u WHERE b.blog_id = wb.blog_id AND b.user_id = u.ID AND b.blog_id = bm.blog_id AND b.blog_id = bm2.blog_id AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'last_activity' AND bm2.meta_key = 'name' AND bm2.meta_value LIKE '%%$filter%%' {$user_sql} {$include_sql} GROUP BY b.blog_id {$order_sql} {$pag_sql}" );
+			$total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2 WHERE b.blog_id = wb.blog_id AND bm.blog_id = b.blog_id AND bm2.blog_id = b.blog_id AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'name' AND bm2.meta_key = 'description' AND ( bm.meta_value LIKE '%%$filter%%' || bm2.meta_value LIKE '%%$filter%%' ) {$user_sql} {$include_sql}" );
 		} else {
-			$paged_blogs = $wpdb->get_results( "SELECT b.blog_id, b.user_id as admin_user_id, u.user_email as admin_user_email, wb.domain, wb.path, bm.meta_value as last_activity, bm2.meta_value as name FROM {$bp->blogs->table_name} b, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2, {$wpdb->base_prefix}blogs wb, {$wpdb->users} u WHERE b.blog_id = wb.blog_id AND b.user_id = u.ID AND b.blog_id = bm.blog_id AND b.blog_id = bm2.blog_id {$user_sql} AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'last_activity' AND bm2.meta_key = 'name' GROUP BY b.blog_id {$order_sql} {$pag_sql}" );
-			$total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb WHERE b.blog_id = wb.blog_id {$user_sql} AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql}" );
+			$paged_blogs = $wpdb->get_results( "SELECT b.blog_id, b.user_id as admin_user_id, u.user_email as admin_user_email, wb.domain, wb.path, bm.meta_value as last_activity, bm2.meta_value as name FROM {$bp->blogs->table_name} b, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2, {$wpdb->base_prefix}blogs wb, {$wpdb->users} u WHERE b.blog_id = wb.blog_id AND b.user_id = u.ID AND b.blog_id = bm.blog_id AND b.blog_id = bm2.blog_id {$user_sql} AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'last_activity' AND bm2.meta_key = 'name' {$include_sql} GROUP BY b.blog_id {$order_sql} {$pag_sql}" );
+			$total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb WHERE b.blog_id = wb.blog_id {$user_sql} AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$include_sql} {$hidden_sql}" );
 		}
 
 		$blog_ids = array();
@@ -124,17 +171,35 @@ class BP_Blogs_Blog {
 
 		$paged_blogs = BP_Blogs_Blog::get_blog_extras( $paged_blogs, $blog_ids, $type );
 
+		if ( $update_meta_cache ) {
+			bp_blogs_update_meta_cache( $blog_ids );
+		}
+
 		return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
 	}
 
-	function delete_blog_for_all( $blog_id ) {
+	/**
+	 * Delete the record of a given blog for all users.
+	 *
+	 * @param int $blog_id The blog being removed from all users.
+	 * @return int|bool Number of rows deleted on success, false on failure.
+	 */
+	public static function delete_blog_for_all( $blog_id ) {
 		global $wpdb, $bp;
 
 		bp_blogs_delete_blogmeta( $blog_id );
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
 	}
 
-	function delete_blog_for_user( $blog_id, $user_id = null ) {
+	/**
+	 * Delete the record of a given blog for a specific user.
+	 *
+	 * @param int $blog_id The blog being removed.
+	 * @param int $user_id Optional. The ID of the user from whom the blog
+	 *        is being removed. If absent, defaults to the logged-in user ID.
+	 * @return int|bool Number of rows deleted on success, false on failure.
+	 */
+	public static function delete_blog_for_user( $blog_id, $user_id = null ) {
 		global $wpdb, $bp;
 
 		if ( !$user_id )
@@ -143,7 +208,15 @@ class BP_Blogs_Blog {
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE user_id = %d AND blog_id = %d", $user_id, $blog_id ) );
 	}
 
-	function delete_blogs_for_user( $user_id = null ) {
+	/**
+	 * Delete all of a user's blog associations in the BP tables.
+	 *
+	 * @param int $user_id Optional. The ID of the user whose blog
+	 *        associations are being deleted. If absent, defaults to
+	 *        logged-in user ID.
+	 * @return int|bool Number of rows deleted on success, false on failure.
+	 */
+	public static function delete_blogs_for_user( $user_id = null ) {
 		global $wpdb, $bp;
 
 		if ( !$user_id )
@@ -152,7 +225,24 @@ class BP_Blogs_Blog {
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE user_id = %d", $user_id ) );
 	}
 
-	function get_blogs_for_user( $user_id = 0, $show_hidden = false ) {
+	/**
+	 * Get all of a user's blogs, as tracked by BuddyPress.
+	 *
+	 * Note that this is different from the WordPress function
+	 * {@link get_blogs_of_user()}; the current method returns only those
+	 * blogs that have been recorded by BuddyPress, while the WP function
+	 * does a true query of a user's blog capabilities.
+	 *
+	 * @param int $user_id Optional. ID of the user whose blogs are being
+	 *        queried. Defaults to logged-in user.
+	 * @param bool $show_hidden Optional. Whether to include blogs that are
+	 *        not marked public. Defaults to true when viewing one's own
+	 *        profile.
+	 * @return array Multidimensional results array, structured as follows:
+	 *           'blogs' - Array of located blog objects
+	 *           'total' - A count of the total blogs for the user.
+	 */
+	public static function get_blogs_for_user( $user_id = 0, $show_hidden = false ) {
 		global $bp, $wpdb;
 
 		if ( !$user_id )
@@ -178,7 +268,16 @@ class BP_Blogs_Blog {
 		return array( 'blogs' => $user_blogs, 'count' => $total_blog_count );
 	}
 
-	function get_blog_ids_for_user( $user_id = 0 ) {
+	/**
+	 * Get IDs of all of a user's blogs, as tracked by BuddyPress.
+	 *
+	 * This method always includes hidden blogs.
+	 *
+	 * @param int $user_id Optional. ID of the user whose blogs are being
+	 *        queried. Defaults to logged-in user.
+	 * @return int The number of blogs associated with the user.
+	 */
+	public static function get_blog_ids_for_user( $user_id = 0 ) {
 		global $bp, $wpdb;
 
 		if ( !$user_id )
@@ -187,13 +286,31 @@ class BP_Blogs_Blog {
 		return $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$bp->blogs->table_name} WHERE user_id = %d", $user_id ) );
 	}
 
-	function is_recorded( $blog_id ) {
+	/**
+	 * Check whether a blog has been recorded by BuddyPress.
+	 *
+	 * @param int $blog_id ID of the blog being queried.
+	 * @return int|null The ID of the first located entry in the BP table
+	 *         on success, otherwise null.
+	 */
+	public static function is_recorded( $blog_id ) {
 		global $bp, $wpdb;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
 	}
 
-	function total_blog_count_for_user( $user_id = null ) {
+	/**
+	 * Return a count of associated blogs for a given user.
+	 *
+	 * Includes hidden blogs when the logged-in user is the same as the
+	 * $user_id parameter, or when the logged-in user has the bp_moderate
+	 * cap.
+	 *
+	 * @param int $user_id Optional. ID of the user whose blogs are being
+	 *        queried. Defaults to logged-in user.
+	 * @return int Blog count for the user.
+	 */
+	public static function total_blog_count_for_user( $user_id = null ) {
 		global $bp, $wpdb;
 
 		if ( !$user_id )
@@ -207,7 +324,22 @@ class BP_Blogs_Blog {
 		}
 	}
 
-	function search_blogs( $filter, $limit = null, $page = null ) {
+	/**
+	 * Return a list of blogs matching a search term.
+	 *
+	 * Matches against blog names and descriptions, as stored in the BP
+	 * blogmeta table.
+	 *
+	 * @param string $filter The search term.
+	 * @param int $limit Optional. The maximum number of items to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page of results to return. Default:
+	 *        null (no limit).
+	 * @return array Multidimensional results array, structured as follows:
+	 *           'blogs' - Array of located blog objects
+	 *           'total' - A count of the total blogs matching the query.
+	 */
+	public static function search_blogs( $filter, $limit = null, $page = null ) {
 		global $wpdb, $bp;
 
 		$filter = esc_sql( like_escape( $filter ) );
@@ -216,6 +348,7 @@ class BP_Blogs_Blog {
 		if ( !bp_current_user_can( 'bp_moderate' ) )
 			$hidden_sql = "AND wb.public = 1";
 
+		$pag_sql = '';
 		if ( $limit && $page ) {
 			$pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
 		}
@@ -226,7 +359,21 @@ class BP_Blogs_Blog {
 		return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
 	}
 
-	function get_all( $limit = null, $page = null ) {
+	/**
+	 * Retrieve a list of all blogs.
+	 *
+	 * Query will include hidden blogs if the logged-in user has the
+	 * 'bp_moderate' cap.
+	 *
+	 * @param int $limit Optional. The maximum number of items to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page of results to return. Default:
+	 *        null (no limit).
+	 * @return array Multidimensional results array, structured as follows:
+	 *           'blogs' - Array of located blog objects
+	 *           'total' - A count of the total blogs.
+	 */
+	public static function get_all( $limit = null, $page = null ) {
 		global $bp, $wpdb;
 
 		$hidden_sql = !bp_current_user_can( 'bp_moderate' ) ? "AND wb.public = 1" : '';
@@ -238,7 +385,22 @@ class BP_Blogs_Blog {
 		return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
 	}
 
-	function get_by_letter( $letter, $limit = null, $page = null ) {
+	/**
+	 * Retrieve a list of blogs whose names start with a given letter.
+	 *
+	 * Query will include hidden blogs if the logged-in user has the
+	 * 'bp_moderate' cap.
+	 *
+	 * @param string $letter. The letter you're looking for.
+	 * @param int $limit Optional. The maximum number of items to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page of results to return. Default:
+	 *        null (no limit).
+	 * @return array Multidimensional results array, structured as follows:
+	 *           'blogs' - Array of located blog objects.
+	 *           'total' - A count of the total blogs matching the query.
+	 */
+	public static function get_by_letter( $letter, $limit = null, $page = null ) {
 		global $bp, $wpdb;
 
 		$letter = esc_sql( like_escape( $letter ) );
@@ -256,7 +418,21 @@ class BP_Blogs_Blog {
 		return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
 	}
 
-	function get_blog_extras( &$paged_blogs, &$blog_ids, $type = false ) {
+	/**
+	 * Fetch blog data not caught in the main query and append it to results array.
+	 *
+	 * Gets the following information, which is either unavailable at the
+	 * time of the original query, or is more efficient to look up in one
+	 * fell swoop:
+	 *   - The latest post for each blog, include Featured Image data
+	 *   - The blog description
+	 *
+	 * @param array $paged_blogs Array of results from the original query.
+	 * @param array $blog_ids Array of IDs returned from the original query.
+	 * @param string|bool $type Not currently used. Default: false.
+	 * @return array $paged_blogs The located blogs array, with the extras added.
+	 */
+	public static function get_blog_extras( &$paged_blogs, &$blog_ids, $type = false ) {
 		global $bp, $wpdb;
 
 		if ( empty( $blog_ids ) )
@@ -310,12 +486,42 @@ class BP_Blogs_Blog {
 		return $paged_blogs;
 	}
 
-	function is_hidden( $blog_id ) {
+	/**
+	 * Check whether a given blog is hidden.
+	 *
+	 * Checks the 'public' column in the wp_blogs table.
+	 *
+	 * @param int $blog_id The ID of the blog being checked.
+	 * @return bool True if hidden (public = 0), false otherwise.
+	 */
+	public static function is_hidden( $blog_id ) {
 		global $wpdb;
 
-		if ( !(int) $wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT public FROM {$wpdb->base_prefix}blogs WHERE blog_id = %d", $blog_id ) ) )
+		if ( !(int) $wpdb->get_var( $wpdb->prepare( "SELECT public FROM {$wpdb->base_prefix}blogs WHERE blog_id = %d", $blog_id ) ) ) {
 			return true;
+		}
 
 		return false;
 	}
+
+	/**
+	 * Get ID of user-blog link.
+	 *
+	 * @param int $user_id ID of user.
+	 * @param int $blog_id ID of blog.
+	 * @return int|bool ID of user-blog link, or false if not found.
+	 */
+	public static function get_user_blog( $user_id, $blog_id ) {
+		global $bp, $wpdb;
+
+		$user_blog = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->blogs->table_name} WHERE user_id = %d AND blog_id = %d", $user_id, $blog_id ) );
+
+		if ( empty( $user_blog ) ) {
+			$user_blog = false;
+		} else {
+			$user_blog = intval( $user_blog );
+		}
+
+		return $user_blog;
+	}
 }
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-filters.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-filters.php
index 99b6ba11378acaf9175d7a141c8fd6fb3050a484..07ad0e3060e5a67c11fc59d1485257236348d599 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-filters.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-filters.php
@@ -5,10 +5,10 @@
  *
  * @package BuddyPress
  * @subpackage Blogs
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 
-// Display filters
+/** Display Filters **********************************************************/
 
 add_filter( 'bp_get_blog_latest_post_title', 'wptexturize'   );
 add_filter( 'bp_get_blog_latest_post_title', 'convert_chars' );
@@ -22,13 +22,15 @@ add_filter( 'bp_blog_latest_post_content', 'shortcode_unautop'  );
 add_filter( 'bp_blog_latest_post_content', 'prepend_attachment' );
 
 /**
- * Ensures that the 'Create a new site' link at wp-admin/my-sites.php points to the BP blog signup
+ * Ensure that the 'Create a new site' link at wp-admin/my-sites.php points to the BP blog signup.
  *
- * @since BuddyPress (1.6)
- * @uses apply_filters() Filter bp_blogs_creation_location to alter the returned value
+ * @since BuddyPress (1.6.0)
  *
- * @param string $url The original URL (points to wp-signup.php by default)
- * @return string The new URL
+ * @uses apply_filters() Filter 'bp_blogs_creation_location' to alter the
+ *       returned value.
+ *
+ * @param string $url The original URL (points to wp-signup.php by default).
+ * @return string The new URL.
  */
 function bp_blogs_creation_location( $url ) {
 	return apply_filters( 'bp_blogs_creation_location', trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/create', $url ) );
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-functions.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-functions.php
index 7ecd4c3acf0dc910a6a50e23e0270bc2cb688142..499e2e78eea87a16716f0f32cce16937fef817a9 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-functions.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-functions.php
@@ -1,14 +1,22 @@
 <?php
+/**
+ * Blogs component functions.
+ *
+ * @package BuddyPress
+ * @subpackage BlogsFunctions
+ */
+
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Checks $bp pages global and looks for directory page
+ * Check whether the $bp global lists an activity directory page.
  *
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @return bool True if set, False if empty
+ * @global BuddyPress $bp The one true BuddyPress instance.
+ *
+ * @return bool True if set, false if empty.
  */
 function bp_blogs_has_directory() {
 	global $bp;
@@ -16,26 +24,44 @@ function bp_blogs_has_directory() {
 	return (bool) !empty( $bp->pages->blogs->id );
 }
 
+/**
+ * Retrieve a set of blogs
+ *
+ * @see BP_Blogs_Blog::get() for a description of arguments and return value.
+ *
+ * @param array $args {
+ *     Arguments are listed here with their default values. For more
+ *     information about the arguments, see {@link BP_Blogs_Blog::get()}.
+ *     @type string $type Default: 'active'.
+ *     @type int|bool $user_id Default: false.
+ *     @type array $include_blog_ids Default: false.
+ *     @type string|bool $search_terms Default: false.
+ *     @type int $per_page Default: 20.
+ *     @type int $page Default: 1.
+ *     @type bool $update_meta_cache Whether to pre-fetch blogmeta. Default: true.
+ * }
+ * @return array See {@link BP_Blogs_Blog::get()}.
+ */
 function bp_blogs_get_blogs( $args = '' ) {
 
 	$defaults = array(
-		'type'         => 'active', // active, alphabetical, newest, or random
-		'user_id'      => false,    // Pass a user_id to limit to only blogs that this user has privilages higher than subscriber on
-		'search_terms' => false,    // Limit to blogs that match these search terms
-		'per_page'     => 20,       // The number of results to return per page
-		'page'         => 1,        // The page to return if limiting per page
+		'type'              => 'active', // active, alphabetical, newest, or random
+		'user_id'           => false,    // Pass a user_id to limit to only blogs that this user has privilages higher than subscriber on
+		'include_blog_ids'  => false,
+		'search_terms'      => false,    // Limit to blogs that match these search terms
+		'per_page'          => 20,       // The number of results to return per page
+		'page'              => 1,        // The page to return if limiting per page
+		'update_meta_cache' => true,
 	);
 
 	$params = wp_parse_args( $args, $defaults );
 	extract( $params, EXTR_SKIP );
 
-	return apply_filters( 'bp_blogs_get_blogs', BP_Blogs_Blog::get( $type, $per_page, $page, $user_id, $search_terms ), $params );
+	return apply_filters( 'bp_blogs_get_blogs', BP_Blogs_Blog::get( $type, $per_page, $page, $user_id, $search_terms, $update_meta_cache, $include_blog_ids ), $params );
 }
 
 /**
- * Populates the BP blogs table with existing blogs.
- *
- * @package BuddyPress Blogs
+ * Populate the BP blogs table with existing blogs.
  *
  * @global object $bp BuddyPress global settings
  * @global object $wpdb WordPress database object
@@ -46,7 +72,7 @@ function bp_blogs_record_existing_blogs() {
 	global $bp, $wpdb;
 
 	// Truncate user blogs table and re-record.
-	$wpdb->query( "TRUNCATE TABLE {$bp->blogs->table_name}" );
+	$wpdb->query( "DELETE FROM {$bp->blogs->table_name} WHERE 1=1" );
 
 	if ( is_multisite() ) {
 		$blog_ids = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$wpdb->base_prefix}blogs WHERE mature = 0 AND spam = 0 AND deleted = 0 AND site_id = %d", $wpdb->siteid ) );
@@ -72,16 +98,18 @@ function bp_blogs_record_existing_blogs() {
 }
 
 /**
- * Makes BuddyPress aware of sites that shouldn't be recorded to activity streams.
+ * Check whether a given blog should be recorded in activity streams.
  *
  * If $user_id is provided, you can restrict site from being recordable
  * only to particular users.
  *
- * @since BuddyPress (1.7)
- * @param int $blog_id
- * @param int|null $user_id
+ * @since BuddyPress (1.7.0)
+ *
  * @uses apply_filters()
- * @return bool True if blog is recordable, false elsewhere
+ *
+ * @param int $blog_id ID of the blog being checked.
+ * @param int $user_id Optional. ID of the user for whom access is being checked.
+ * @return bool True if blog is recordable, otherwise false.
  */
 function bp_blogs_is_blog_recordable( $blog_id, $user_id = 0 ) {
 
@@ -101,16 +129,19 @@ function bp_blogs_is_blog_recordable( $blog_id, $user_id = 0 ) {
 }
 
 /**
- * Makes BuddyPress aware of sites that activities shouldn't be trackable.
+ * Check whether a given blog should be tracked by the Blogs component.
+ *
  * If $user_id is provided, the developer can restrict site from
  * being trackable only to particular users.
  *
- * @since BuddyPress (1.7)
- * @param int $blog_id
- * @param int|null $user_id
+ * @since BuddyPress (1.7.0)
+ *
  * @uses bp_blogs_is_blog_recordable
  * @uses apply_filters()
- * @return bool True if blog is trackable, false elsewhere
+ *
+ * @param int $blog_id ID of the blog being checked.
+ * @param int $user_id Optional. ID of the user for whom access is being checked.
+ * @return bool True if blog is trackable, otherwise false.
  */
 function bp_blogs_is_blog_trackable( $blog_id, $user_id = 0 ) {
 
@@ -130,13 +161,17 @@ function bp_blogs_is_blog_trackable( $blog_id, $user_id = 0 ) {
 }
 
 /**
- * Makes BuddyPress aware of a new site so that it can track its activity.
+ * Make BuddyPress aware of a new site so that it can track its activity.
+ *
+ * @since BuddyPress (1.0.0)
  *
- * @since BuddyPress (1.0)
- * @param int $blog_id
- * @param int $user_id
- * @param bool $no_activity Optional; defaults to false
  * @uses BP_Blogs_Blog
+ *
+ * @param int $blog_id ID of the blog being recorded.
+ * @param int $user_id ID of the user for whom the blog is being recorded.
+ * @param bool $no_activity Optional. Whether to skip recording an activity
+ *        item about this blog creation. Default: false.
+ * @return bool|null Returns false on failure.
  */
 function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
 
@@ -147,11 +182,24 @@ function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
 	if ( !bp_blogs_is_blog_recordable( $blog_id, $user_id ) )
 		return false;
 
-	$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;
@@ -159,9 +207,13 @@ function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
 	$recorded_blog_id       = $recorded_blog->save();
 	$is_recorded            = !empty( $recorded_blog_id ) ? true : false;
 
+	bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'url', $url );
 	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 );
@@ -172,8 +224,7 @@ function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
 		// Record this in activity streams
 		bp_blogs_record_activity( array(
 			'user_id'      => $recorded_blog->user_id,
-			'action'       => apply_filters( 'bp_blogs_activity_created_blog_action', sprintf( __( '%s created the site %s', 'buddypress'), bp_core_get_userlink( $recorded_blog->user_id ), '<a href="' . get_home_url( $recorded_blog->blog_id ) . '">' . esc_attr( $name ) . '</a>' ), $recorded_blog, $name, $description ),
-			'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', get_home_url( $recorded_blog->blog_id ), $recorded_blog->blog_id ),
+			'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', $url, $recorded_blog->blog_id ),
 			'type'         => 'new_blog',
 			'item_id'      => $recorded_blog->blog_id
 		) );
@@ -184,11 +235,13 @@ function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
 add_action( 'wpmu_new_blog', 'bp_blogs_record_blog', 10, 2 );
 
 /**
- * Updates blogname in BuddyPress blogmeta table
+ * Update blog name in BuddyPress blogmeta table.
  *
- * @global object $wpdb DB Layer
- * @param string $oldvalue Value before save (not used)
- * @param string $newvalue Value to change meta to
+ * @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_blogname( $oldvalue, $newvalue ) {
 	global $wpdb;
@@ -198,11 +251,13 @@ function bp_blogs_update_option_blogname( $oldvalue, $newvalue ) {
 add_action( 'update_option_blogname', 'bp_blogs_update_option_blogname', 10, 2 );
 
 /**
- * Updates blogdescription in BuddyPress blogmeta table
+ * Update blog description in BuddyPress blogmeta table
+ *
+ * @global object $wpdb DB Layer.
  *
- * @global object $wpdb DB Layer
- * @param string $oldvalue Value before save (not used)
- * @param string $newvalue Value to change meta to
+ * @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_blogdescription( $oldvalue, $newvalue ) {
 	global $wpdb;
@@ -211,6 +266,147 @@ function bp_blogs_update_option_blogdescription( $oldvalue, $newvalue ) {
 }
 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)
+ * they have not already been published. This enables proper posting for
+ * regular posts as well as scheduled posts, while preventing post bumping.
+ *
+ * See #4090, #3746, #2546 for background.
+ *
+ * @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 ) {
+
+	// This is an edit
+	if ( $new_status === $old_status ) {
+		if ( $new_status == 'publish' ) {
+			bp_blogs_update_post( $post );
+			return;
+		}
+	}
+
+	// Publishing a previously unpublished post
+	if ( 'publish' === $new_status ) {
+		// 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 ) {
+		// 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 );
+
+/**
+ * Record a new blog post in the BuddyPress activity stream.
+ *
+ * @param int $post_id ID of the post being recorded.
+ * @param object $post The WP post object passed to the 'save_post' action.
+ * @param int $user_id Optional. The user to whom the activity item will be
+ *        associated. Defaults to the post_author.
+ * @return bool|null Returns false on failure.
+ */
 function bp_blogs_record_post( $post_id, $post, $user_id = 0 ) {
 	global $bp, $wpdb;
 
@@ -246,7 +442,11 @@ function bp_blogs_record_post( $post_id, $post, $user_id = 0 ) {
 		if ( $is_blog_public || !is_multisite() ) {
 
 			// Record this in activity streams
-			$post_permalink   = get_permalink( $post_id );
+			$post_permalink = add_query_arg(
+				'p',
+				$post_id,
+				trailingslashit( get_home_url( $blog_id ) )
+			);
 
 			if ( is_multisite() )
 				$activity_action  = sprintf( __( '%1$s wrote a new post, %2$s, on the site %3$s', 'buddypress' ), bp_core_get_userlink( (int) $post->post_author ), '<a href="' . $post_permalink . '">' . $post->post_title . '</a>', '<a href="' . get_blog_option( $blog_id, 'home' ) . '">' . get_blog_option( $blog_id, 'blogname' ) . '</a>' );
@@ -272,13 +472,12 @@ function bp_blogs_record_post( $post_id, $post, $user_id = 0 ) {
 
 			bp_blogs_record_activity( array(
 				'user_id'           => (int) $post->post_author,
-				'action'            => apply_filters( 'bp_blogs_activity_new_post_action',       $activity_action,  $post, $post_permalink ),
 				'content'           => apply_filters( 'bp_blogs_activity_new_post_content',      $activity_content, $post, $post_permalink ),
 				'primary_link'      => apply_filters( 'bp_blogs_activity_new_post_primary_link', $post_permalink,   $post_id               ),
 				'type'              => 'new_blog_post',
 				'item_id'           => $blog_id,
 				'secondary_item_id' => $post_id,
-				'recorded_time'     => $post->post_modified_gmt
+				'recorded_time'     => $post->post_date_gmt,
 			));
 		}
 
@@ -290,15 +489,55 @@ function bp_blogs_record_post( $post_id, $post, $user_id = 0 ) {
 
 	do_action( 'bp_blogs_new_blog_post', $post_id, $post, $user_id );
 }
-add_action( 'save_post', 'bp_blogs_record_post', 10, 2 );
 
 /**
- * Record blog comment activity. Checks if blog is public and post is not
- * password protected.
+ * 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.
  *
- * @param int $comment_id
- * @param mixed $is_approved
- * @return mixed
+ * @param int $comment_id ID of the comment being recorded.
+ * @param bool|string $is_approved Optional. The $is_approved value passed to
+ *        the 'comment_post' action. Default: true.
+ * @return bool|object Returns false on failure, the comment object on success.
  */
 function bp_blogs_record_comment( $comment_id, $is_approved = true ) {
 	// Get the users comment
@@ -353,27 +592,97 @@ function bp_blogs_record_comment( $comment_id, $is_approved = true ) {
 
 		// Get activity related links
 		$post_permalink = get_permalink( $recorded_comment->comment_post_ID );
-		$comment_link   = htmlspecialchars( get_comment_link( $recorded_comment->comment_ID ) );
+		$comment_link   = get_comment_link( $recorded_comment->comment_ID );
+
+		// 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;
+				}
+			}
 
-		// 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>' );
+			// find the parent 'new_blog_post' activity entry
+			$parent_activity_id = bp_activity_get_activity_id( array(
+				'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 );
+				}
 
-		$activity_content	= $recorded_comment->comment_content;
+				// 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;
+				}
 
-		// Record in activity streams
-		bp_blogs_record_activity( array(
-			'user_id'           => $user_id,
-			'action'            => apply_filters_ref_array( 'bp_blogs_activity_new_comment_action',       array( $activity_action,  &$recorded_comment, $comment_link ) ),
-			'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
-		) );
+				$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() );
@@ -384,6 +693,22 @@ function bp_blogs_record_comment( $comment_id, $is_approved = true ) {
 add_action( 'comment_post', 'bp_blogs_record_comment', 10, 2 );
 add_action( 'edit_comment', 'bp_blogs_record_comment', 10    );
 
+/**
+ * Record a user's association with a blog.
+ *
+ * This function is hooked to several WordPress actions where blog roles are
+ * set/changed ('add_user_to_blog', 'profile_update', 'user_register'). It
+ * parses the changes, and records them as necessary in the BP blog tracker.
+ *
+ * BuddyPress does not track blogs for Subscribers.
+ *
+ * @param int $user_id The ID of the user.
+ * @param string|bool $role The WP role being assigned to the user
+ *        ('subscriber', 'contributor', 'author', 'editor', 'administrator', or
+ *        a custom role). Defaults to false.
+ * @param int $blog_id Default: the current blog ID.
+ * @return bool|null False on failure.
+ */
 function bp_blogs_add_user_to_blog( $user_id, $role = false, $blog_id = 0 ) {
 	global $wpdb;
 
@@ -409,6 +734,12 @@ add_action( 'add_user_to_blog', 'bp_blogs_add_user_to_blog', 10, 3 );
 add_action( 'profile_update',   'bp_blogs_add_user_to_blog'        );
 add_action( 'user_register',    'bp_blogs_add_user_to_blog'        );
 
+/**
+ * Remove a blog-user pair from BP's blog tracker.
+ *
+ * @param int $user_id ID of the user whose blog is being removed.
+ * @param int $blog_id Optional. ID of the blog being removed. Default: current blog ID.
+ */
 function bp_blogs_remove_user_from_blog( $user_id, $blog_id = 0 ) {
 	global $wpdb;
 
@@ -420,13 +751,15 @@ function bp_blogs_remove_user_from_blog( $user_id, $blog_id = 0 ) {
 add_action( 'remove_user_from_blog', 'bp_blogs_remove_user_from_blog', 10, 2 );
 
 /**
- * Rehooks WP's maybe_add_existing_user_to_blog with a later priority
+ * Rehook WP's maybe_add_existing_user_to_blog with a later priority
  *
- * WordPress catches add-user-to-blog requests at init:10. In some cases, this can precede BP's
- * Blogs component. This function bumps the priority of the core function, so that we can be sure
- * that the Blogs component is loaded first. See http://buddypress.trac.wordpress.org/ticket/3916
+ * WordPress catches add-user-to-blog requests at init:10. In some cases, this
+ * can precede BP's Blogs component. This function bumps the priority of the
+ * core function, so that we can be sure that the Blogs component is loaded
+ * first. See http://buddypress.trac.wordpress.org/ticket/3916.
  *
  * @since BuddyPress (1.6)
+ * @access private
  */
 function bp_blogs_maybe_add_user_to_blog() {
 	if ( ! is_multisite() )
@@ -437,6 +770,11 @@ function bp_blogs_maybe_add_user_to_blog() {
 }
 add_action( 'init', 'bp_blogs_maybe_add_user_to_blog', 1 );
 
+/**
+ * Remove the "blog created" item from the BP blogs tracker and activity stream.
+ *
+ * @param int $blog_id ID of the blog being removed.
+ */
 function bp_blogs_remove_blog( $blog_id ) {
 	global $bp;
 
@@ -452,6 +790,12 @@ function bp_blogs_remove_blog( $blog_id ) {
 }
 add_action( 'delete_blog', 'bp_blogs_remove_blog' );
 
+/**
+ * Remove a blog from the tracker for a specific user.
+ *
+ * @param int $user_id ID of the user for whom the blog is being removed.
+ * @param int $blog_id ID of the blog being removed.
+ */
 function bp_blogs_remove_blog_for_user( $user_id, $blog_id ) {
 	global $bp;
 
@@ -473,6 +817,14 @@ function bp_blogs_remove_blog_for_user( $user_id, $blog_id ) {
 }
 add_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
 
+/**
+ * Remove a blog post activity item from the activity stream.
+ *
+ * @param int $post_id ID of the post to be removed.
+ * @param int $blog_id Optional. Defaults to current blog ID.
+ * @param int $user_id Optional. Defaults to the logged-in user ID. This param
+ *        is currently unused in the function (but is passed to hooks).
+ */
 function bp_blogs_remove_post( $post_id, $blog_id = 0, $user_id = 0 ) {
 	global $wpdb, $bp;
 
@@ -496,24 +848,116 @@ function bp_blogs_remove_post( $post_id, $blog_id = 0, $user_id = 0 ) {
 }
 add_action( 'delete_post', 'bp_blogs_remove_post' );
 
+/**
+ * Remove a blog comment activity item from the activity stream.
+ *
+ * @param int $comment_id ID of the comment to be removed.
+ */
 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.
  *
- * @global object $bp BuddyPress global settings
+ * @since BuddyPress (1.6.0)
+ *
+ * @global object $bp BuddyPress global settings.
+ *
  * @param string $new_status New comment status.
  * @param string $old_status Previous comment status.
  * @param object $comment Comment data.
- * @since BuddyPress (1.6)
  */
 function bp_blogs_transition_activity_status( $new_status, $old_status, $comment ) {
 	global $bp;
@@ -528,28 +972,34 @@ function bp_blogs_transition_activity_status( $new_status, $old_status, $comment
 	 * If a blog comment transitions to a "delete" or "hold" status, delete the activity item.
 	 * If a blog comment transitions to trashed, or spammed, mark the activity as spam.
 	 * If a blog comment transitions to approved (and the activity exists), mark the activity as ham.
+	 * If a blog comment transitions to unapproved (and the activity exists), mark the activity as spam.
 	 * Otherwise, record the comment into the activity stream.
 	 */
 
 	// 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', 'unapproved' ) ) ) {
 		$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;
 	}
@@ -578,6 +1028,11 @@ function bp_blogs_transition_activity_status( $new_status, $old_status, $comment
 }
 add_action( 'transition_comment_status', 'bp_blogs_transition_activity_status', 10, 3 );
 
+/**
+ * Get the total number of blogs being tracked by BuddyPress.
+ *
+ * @return int $count Total blog count.
+ */
 function bp_blogs_total_blogs() {
 	if ( !$count = wp_cache_get( 'bp_total_blogs', 'bp' ) ) {
 		$blogs = BP_Blogs_Blog::get_all();
@@ -587,6 +1042,13 @@ function bp_blogs_total_blogs() {
 	return $count;
 }
 
+/**
+ * Get the total number of blogs being tracked by BP for a specific user.
+ *
+ * @param int $user_id ID of the user being queried. Default: on a user page,
+ *        the displayed user. Otherwise, the logged-in user.
+ * @return int $count Total blog count for the user.
+ */
 function bp_blogs_total_blogs_for_user( $user_id = 0 ) {
 
 	if ( empty( $user_id ) )
@@ -600,6 +1062,11 @@ function bp_blogs_total_blogs_for_user( $user_id = 0 ) {
 	return $count;
 }
 
+/**
+ * Remove the all data related to a given blog from the BP blogs tracker and activity stream.
+ *
+ * @param int $blog_id The ID of the blog to expunge.
+ */
 function bp_blogs_remove_data_for_blog( $blog_id ) {
 	global $bp;
 
@@ -615,18 +1082,54 @@ function bp_blogs_remove_data_for_blog( $blog_id ) {
 }
 add_action( 'delete_blog', 'bp_blogs_remove_data_for_blog', 1 );
 
+/**
+ * Get all of a user's blogs, as tracked by BuddyPress.
+ *
+ * @see BP_Blogs_Blog::get_blogs_for_user() for a description of parameters
+ *      and return values.
+ *
+ * @param int $user_id See {@BP_Blogs_Blog::get_blogs_for_user()}.
+ * @param bool $show_hidden See {@BP_Blogs_Blog::get_blogs_for_user()}.
+ * @return array See {@BP_Blogs_Blog::get_blogs_for_user()}.
+ */
 function bp_blogs_get_blogs_for_user( $user_id, $show_hidden = false ) {
 	return BP_Blogs_Blog::get_blogs_for_user( $user_id, $show_hidden );
 }
 
+/**
+ * Retrieve a list of all blogs.
+ *
+ * @see BP_Blogs_Blog::get_all() for a description of parameters and return values.
+ *
+ * @param int $limit See {@BP_Blogs_Blog::get_all()}.
+ * @param int $page See {@BP_Blogs_Blog::get_all()}.
+ * @return array See {@BP_Blogs_Blog::get_all()}.
+ */
 function bp_blogs_get_all_blogs( $limit = null, $page = null ) {
 	return BP_Blogs_Blog::get_all( $limit, $page );
 }
 
+/**
+ * Retrieve a random list of blogs.
+ *
+ * @see BP_Blogs_Blog::get() for a description of parameters and return values.
+ *
+ * @param int $limit See {@BP_Blogs_Blog::get()}.
+ * @param int $page See {@BP_Blogs_Blog::get()}.
+ * @return array See {@BP_Blogs_Blog::get()}.
+ */
 function bp_blogs_get_random_blogs( $limit = null, $page = null ) {
 	return BP_Blogs_Blog::get( 'random', $limit, $page );
 }
 
+/**
+ * Check whether a given blog is hidden.
+ *
+ * @see BP_Blogs_Blog::is_hidden() for a description of parameters and return values.
+ *
+ * @param int $blog_id See {@BP_Blogs_Blog::is_hidden()}.
+ * @return bool See {@BP_Blogs_Blog::is_hidden()}.
+ */
 function bp_blogs_is_blog_hidden( $blog_id ) {
 	return BP_Blogs_Blog::is_hidden( $blog_id );
 }
@@ -640,95 +1143,121 @@ function bp_blogs_is_blog_hidden( $blog_id ) {
  * stored and synced here.
  */
 
-function bp_blogs_delete_blogmeta( $blog_id, $meta_key = false, $meta_value = false ) {
-	global $wpdb, $bp;
-
-	if ( !is_numeric( $blog_id ) )
-		return false;
-
-	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
-
-	if ( is_array($meta_value) || is_object($meta_value) )
-		$meta_value = serialize($meta_value);
-
-	$meta_value = trim( $meta_value );
-
-	if ( !$meta_key )
-		$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d", $blog_id ) );
-	else if ( $meta_value )
-		$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s AND meta_value = %s", $blog_id, $meta_key, $meta_value ) );
-	else
-		$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
-
-	wp_cache_delete( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, 'bp' );
-
-	return true;
-}
-
-function bp_blogs_get_blogmeta( $blog_id, $meta_key = '') {
+/**
+ * Delete a metadta from the DB for a blog.
+ *
+ * @global object $wpdb WordPress database access object.
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param int $blog_id ID of the blog whose metadata is being deleted.
+ * @param string $meta_key Optional. The key of the metadata being deleted. If
+ *        omitted, all BP metadata associated with the blog will be deleted.
+ * @param string $meta_value Optional. If present, the metadata will only be
+ *        deleted if the meta_value matches this parameter.
+ * @param bool $delete_all Optional. If true, delete matching metadata entries
+ * 	  for all objects, ignoring the specified blog_id. Otherwise, only
+ * 	  delete matching metadata entries for the specified blog.
+ * 	  Default: false.
+ * @return bool True on success, false on failure.
+ */
+function bp_blogs_delete_blogmeta( $blog_id, $meta_key = false, $meta_value = false, $delete_all = false ) {
 	global $wpdb, $bp;
 
-	$blog_id = (int) $blog_id;
-
-	if ( !$blog_id )
-		return false;
-
-	if ( !empty($meta_key) ) {
-		$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
-
-		if ( !$metas = wp_cache_get( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, 'bp' ) ) {
-			$metas = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
-			wp_cache_set( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, $metas, 'bp' );
-		}
+	// Legacy - if no meta_key is passed, delete all for the blog_id
+	if ( empty( $meta_key ) ) {
+		$keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$wpdb->blogmeta} WHERE blog_id = %d", $blog_id ) );
+		$delete_all = false;
 	} else {
-		$metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d", $blog_id ) );
+		$keys = array( $meta_key );
 	}
 
-	if ( empty($metas) ) {
-		if ( empty($meta_key) )
-			return array();
-		else
-			return '';
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+
+	$retval = false;
+	foreach ( $keys as $key ) {
+		$retval = delete_metadata( 'blog', $blog_id, $key, $meta_value, $delete_all );
 	}
 
-	$metas = array_map('maybe_unserialize', (array) $metas);
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	if ( 1 == count($metas) )
-		return $metas[0];
-	else
-		return $metas;
+	return $retval;
 }
 
-function bp_blogs_update_blogmeta( $blog_id, $meta_key, $meta_value ) {
-	global $wpdb, $bp;
-
-	if ( !is_numeric( $blog_id ) )
-		return false;
-
-	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-	if ( is_string($meta_value) )
-		$meta_value = stripslashes( esc_sql( $meta_value ) );
-
-	$meta_value = maybe_serialize($meta_value);
+/**
+ * Get metadata for a given blog.
+ *
+ * @since BuddyPress (1.2.0)
+ *
+ * @global object $wpdb WordPress database access object.
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param int $blog_id ID of the blog whose metadata is being requested.
+ * @param string $meta_key Optional. If present, only the metadata matching
+ *        that meta key will be returned. Otherwise, all metadata for the
+ *        blog will be fetched.
+ * @param bool $single Optional. If true, return only the first value of the
+ *	  specified meta_key. This parameter has no effect if meta_key is not
+ *	  specified. Default: true.
+ * @return mixed The meta value(s) being requested.
+ */
+function bp_blogs_get_blogmeta( $blog_id, $meta_key = '', $single = true ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = get_metadata( 'blog', $blog_id, $meta_key, $single );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	if (empty( $meta_value ) )
-		return bp_blogs_delete_blogmeta( $blog_id, $meta_key );
+	return $retval;
+}
 
-	$cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
+/**
+ * Update a piece of blog meta.
+ *
+ * @global object $wpdb WordPress database access object.
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param int $blog_id ID of the blog whose metadata is being updated.
+ * @param string $meta_key Key of the metadata being updated.
+ * @param mixed $meta_value Value to be set.
+ * @param mixed $prev_value Optional. If specified, only update existing
+ *        metadata entries with the specified value. Otherwise, update all
+ *        entries.
+ * @return bool|int Returns false on failure. On successful update of existing
+ *         metadata, returns true. On successful creation of new metadata,
+ *         returns the integer ID of the new metadata row.
+ */
+function bp_blogs_update_blogmeta( $blog_id, $meta_key, $meta_value, $prev_value = '' ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = update_metadata( 'blog', $blog_id, $meta_key, $meta_value, $prev_value );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	if ( !$cur )
-		$wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->blogs->table_name_blogmeta} ( blog_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $blog_id, $meta_key, $meta_value ) );
-	else if ( $cur->meta_value != $meta_value )
-		$wpdb->query( $wpdb->prepare( "UPDATE {$bp->blogs->table_name_blogmeta} SET meta_value = %s WHERE blog_id = %d AND meta_key = %s", $meta_value, $blog_id, $meta_key ) );
-	else
-		return false;
+	return $retval;
+}
 
-	wp_cache_set( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, $meta_value, 'bp' );
+/**
+ * Add a piece of blog metadata.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $blog_id ID of the blog.
+ * @param string $meta_key Metadata key.
+ * @param mixed $meta_value Metadata value.
+ * @param bool $unique. Optional. Whether to enforce a single metadata value
+ *        for the given key. If true, and the object already has a value for
+ *        the key, no change will be made. Default: false.
+ * @return int|bool The meta ID on successful update, false on failure.
+ */
+function bp_blogs_add_blogmeta( $blog_id, $meta_key, $meta_value, $unique = false ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = add_metadata( 'blog', $blog_id, $meta_key, $meta_value, $unique );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	return true;
+	return $retval;
 }
-
+/**
+ * Remove all blog associations for a given user.
+ *
+ * @param int $user_id ID whose blog data should be removed.
+ * @return bool|null Returns false on failure.
+ */
 function bp_blogs_remove_data( $user_id ) {
 	if ( !is_multisite() )
 		return false;
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-loader.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-loader.php
index a4762731453c66d4406f4bf2ff6f17bfe615431e..89cf2a16ea4f7eaa18dbe25c7cfc10ff7169756f 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-loader.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-loader.php
@@ -15,29 +15,35 @@ if ( !defined( 'ABSPATH' ) ) exit;
 class BP_Blogs_Component extends BP_Component {
 
 	/**
-	 * Start the blogs component creation process
+	 * Start the blogs component creation process.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'blogs',
 			__( 'Site Tracking', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 30
+			)
 		);
 	}
 
 	/**
-	 * Setup globals
+	 * Set up global settings for the blogs component.
 	 *
 	 * The BP_BLOGS_SLUG constant is deprecated, and only used here for
 	 * backwards compatibility.
 	 *
-	 * @since BuddyPress (1.5)
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @see BP_Component::setup_globals() for description of parameters.
+	 *
+	 * @param array $args See {@link BP_Component::setup_globals()}.
 	 */
 	public function setup_globals( $args = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		if ( !defined( 'BP_BLOGS_SLUG' ) )
 			define ( 'BP_BLOGS_SLUG', $this->id );
@@ -48,9 +54,13 @@ class BP_Blogs_Component extends BP_Component {
 			'table_name_blogmeta' => $bp->table_prefix . 'bp_user_blogs_blogmeta',
 		);
 
+		$meta_tables = array(
+			'blog' => $bp->table_prefix . 'bp_user_blogs_blogmeta',
+		);
+
 		// All globals for messaging component.
 		// Note that global_tables is included in this array.
-		$globals = array(
+		$args = array(
 			'slug'                  => BP_BLOGS_SLUG,
 			'root_slug'             => isset( $bp->pages->blogs->slug ) ? $bp->pages->blogs->slug : BP_BLOGS_SLUG,
 			'has_directory'         => is_multisite(), // Non-multisite installs don't need a top-level Sites directory, since there's only one site
@@ -58,14 +68,19 @@ class BP_Blogs_Component extends BP_Component {
 			'search_string'         => __( 'Search sites...', 'buddypress' ),
 			'autocomplete_all'      => defined( 'BP_MESSAGES_AUTOCOMPLETE_ALL' ),
 			'global_tables'         => $global_tables,
+			'meta_tables'           => $meta_tables,
 		);
 
 		// Setup the globals
-		parent::setup_globals( $globals );
+		parent::setup_globals( $args );
 	}
 
 	/**
-	 * Include files
+	 * Include bp-blogs files.
+	 *
+	 * @see BP_Component::includes() for description of parameters.
+	 *
+	 * @param array $includes See {@link BP_Component::includes()}.
 	 */
 	public function includes( $includes = array() ) {
 		// Files to include
@@ -89,12 +104,17 @@ class BP_Blogs_Component extends BP_Component {
 	}
 
 	/**
-	 * Setup BuddyBar navigation
+	 * Set up component navigation for bp-blogs.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * @see BP_Component::setup_nav() for a description of arguments.
+	 *
+	 * @param array $main_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
+	 * @param array $sub_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		/**
 		 * Blog/post/comment menus should not appear on single WordPress setups.
@@ -104,8 +124,6 @@ class BP_Blogs_Component extends BP_Component {
 		if ( !is_multisite() )
 			return false;
 
-		$sub_nav = array();
-
 		// Add 'Sites' to the main navigation
 		$main_nav =  array(
 			'name'                => sprintf( __( 'Sites <span>%d</span>', 'buddypress' ), bp_blogs_total_blogs_for_user() ),
@@ -141,30 +159,32 @@ class BP_Blogs_Component extends BP_Component {
 	}
 
 	/**
-	 * Set up the Toolbar
+	 * Set up bp-blogs integration with the WordPress admin bar.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @see BP_Component::setup_admin_bar() for a description of arguments.
+	 *
+	 * @param array $wp_admin_nav See BP_Component::setup_admin_bar()
+	 *        for description.
 	 */
 	public function setup_admin_bar( $wp_admin_nav = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		/**
-		 * Blog/post/comment menus should not appear on single WordPress setups.
+		 * Site/post/comment menus should not appear on single WordPress setups.
 		 * Although comments and posts made by users will still show on their
 		 * activity stream.
 		 */
 		if ( !is_multisite() )
 			return false;
 
-		// Prevent debug notices
-		$wp_admin_nav = array();
-
 		// Menus for logged in user
 		if ( is_user_logged_in() ) {
 
 			$blogs_link = trailingslashit( bp_loggedin_user_domain() . $this->slug );
 
-			// Add the "Blogs" sub menu
+			// Add the "Sites" sub menu
 			$wp_admin_nav[] = array(
 				'parent' => $bp->my_account_menu_id,
 				'id'     => 'my-account-' . $this->id,
@@ -172,7 +192,7 @@ class BP_Blogs_Component extends BP_Component {
 				'href'   => trailingslashit( $blogs_link )
 			);
 
-			// My Blogs
+			// My Sites
 			$wp_admin_nav[] = array(
 				'parent' => 'my-account-' . $this->id,
 				'id'     => 'my-account-' . $this->id . '-my-sites',
@@ -180,12 +200,12 @@ class BP_Blogs_Component extends BP_Component {
 				'href'   => trailingslashit( $blogs_link )
 			);
 
-			// Create a Blog
+			// Create a Site
 			if ( bp_blog_signup_enabled() ) {
 				$wp_admin_nav[] = array(
 					'parent' => 'my-account-' . $this->id,
 					'id'     => 'my-account-' . $this->id . '-create',
-					'title'  => __( 'Create a Blog', 'buddypress' ),
+					'title'  => __( 'Create a Site', 'buddypress' ),
 					'href'   => trailingslashit( bp_get_blogs_directory_permalink() . 'create' )
 				);
 			}
@@ -195,14 +215,12 @@ class BP_Blogs_Component extends BP_Component {
 	}
 
 	/**
-	 * Sets up the title for pages and <title>
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * Set up the title for pages and <title>
 	 */
-	function setup_title() {
-		global $bp;
+	public function setup_title() {
+		$bp = buddypress();
 
-		// Set up the component options navigation for Blog
+		// Set up the component options navigation for Site
 		if ( bp_is_blogs_component() ) {
 			if ( bp_is_my_profile() ) {
 				if ( bp_is_active( 'xprofile' ) ) {
@@ -225,8 +243,10 @@ class BP_Blogs_Component extends BP_Component {
 	}
 }
 
+/**
+ * Set up the bp-blogs component.
+ */
 function bp_setup_blogs() {
-	global $bp;
-	$bp->blogs = new BP_Blogs_Component();
+	buddypress()->blogs = new BP_Blogs_Component();
 }
 add_action( 'bp_setup_components', 'bp_setup_blogs', 6 );
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-screens.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-screens.php
index 72bd7dd3de38b35caa758c3000b2af0091fdb75f..bd62ece7dee64b967df061d72f2b2b8aeb0b4bbf 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-screens.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-screens.php
@@ -10,6 +10,9 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Load the "My Blogs" screen.
+ */
 function bp_blogs_screen_my_blogs() {
 	if ( !is_multisite() )
 		return false;
@@ -19,6 +22,9 @@ function bp_blogs_screen_my_blogs() {
 	bp_core_load_template( apply_filters( 'bp_blogs_template_my_blogs', 'members/single/home' ) );
 }
 
+/**
+ * Load the "Create a Blog" screen.
+ */
 function bp_blogs_screen_create_a_blog() {
 
 	if ( !is_multisite() ||  !bp_is_blogs_component() || !bp_is_current_action( 'create' ) )
@@ -33,8 +39,11 @@ function bp_blogs_screen_create_a_blog() {
 }
 add_action( 'bp_screens', 'bp_blogs_screen_create_a_blog', 3 );
 
+/**
+ * Load the top-level Blogs directory.
+ */
 function bp_blogs_screen_index() {
-	if ( is_multisite() && bp_is_blogs_component() && !bp_current_action() ) {
+	if ( bp_is_blogs_directory() ) {
 		bp_update_is_directory( true, 'blogs' );
 
 		do_action( 'bp_blogs_screen_index' );
@@ -47,28 +56,28 @@ add_action( 'bp_screens', 'bp_blogs_screen_index', 2 );
 /** Theme Compatability *******************************************************/
 
 /**
- * The main theme compat class for BuddyPress Activity
+ * The main theme compat class for BuddyPress Blogs
  *
  * This class sets up the necessary theme compatability actions to safely output
  * group template parts to the_title and the_content areas of a theme.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 class BP_Blogs_Theme_Compat {
 
 	/**
-	 * Setup the groups component theme compatibility
+	 * Set up theme compatibility for the Blogs component.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __construct() {
 		add_action( 'bp_setup_theme_compat', array( $this, 'is_blogs' ) );
 	}
 
 	/**
-	 * Are we looking at something that needs group theme compatability?
+	 * Are we looking at something that needs Blogs theme compatability?
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function is_blogs() {
 
@@ -94,7 +103,7 @@ class BP_Blogs_Theme_Compat {
 		} elseif ( is_user_logged_in() && bp_blog_signup_enabled() ) {
 			add_filter( 'bp_get_buddypress_template',                array( $this, 'create_template_hierarchy' ) );
 			add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'create_dummy_post' ) );
-			add_filter( 'bp_replace_the_content',                    array( $this, 'create_content'    ) );			
+			add_filter( 'bp_replace_the_content',                    array( $this, 'create_content'    ) );
 		}
 	}
 
@@ -103,11 +112,13 @@ class BP_Blogs_Theme_Compat {
 	/**
 	 * Add template hierarchy to theme compat for the blog directory page.
 	 *
-	 * This is to mirror how WordPress has {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
+	 * This is to mirror how WordPress has
+	 * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 *
-	 * @param string $templates The templates from bp_get_theme_compat_templates()
+	 * @param string $templates The templates from
+	 *        bp_get_theme_compat_templates().
 	 * @return array $templates Array of custom templates to look for.
 	 */
 	public function directory_template_hierarchy( $templates ) {
@@ -124,18 +135,13 @@ class BP_Blogs_Theme_Compat {
 	}
 
 	/**
-	 * Update the global $post with directory data
+	 * Update the global $post with directory data.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function directory_dummy_post() {
 
-		// Title based on ability to create blogs
-		if ( is_user_logged_in() && bp_blog_signup_enabled() ) {
-			$title = __( 'Blogs', 'buddypress' ) . '&nbsp;<a class="button" href="' . trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/create' ) . '">' . __( 'Create a Blog', 'buddypress' ) . '</a>';
-		} else {
-			$title = __( 'Blogs', 'buddypress' );
-		}
+		$title = apply_filters( 'bp_blogs_directory_header', __( 'Sites', 'buddypress' ) );
 
 		bp_theme_compat_reset_post( array(
 			'ID'             => 0,
@@ -145,30 +151,32 @@ class BP_Blogs_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => 'bp_blogs',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
 
 	/**
-	 * Filter the_content with the groups index template part
+	 * Filter the_content with the groups index template part.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function directory_content() {
-		bp_buffer_template_part( 'blogs/index' );
+		return bp_buffer_template_part( 'blogs/index', null, false );
 	}
-	
+
 	/** Create ****************************************************************/
 
 	/**
 	 * Add custom template hierarchy to theme compat for the blog create page.
 	 *
-	 * This is to mirror how WordPress has {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
+	 * This is to mirror how WordPress has
+	 * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 *
-	 * @param string $templates The templates from bp_get_theme_compat_templates()
+	 * @param string $templates The templates from
+	 *        bp_get_theme_compat_templates().
 	 * @return array $templates Array of custom templates to look for.
 	 */
 	public function create_template_hierarchy( $templates ) {
@@ -185,17 +193,17 @@ class BP_Blogs_Theme_Compat {
 	}
 
 	/**
-	 * Update the global $post with create screen data
+	 * Update the global $post with create screen data.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function create_dummy_post() {
 
 		// Title based on ability to create blogs
 		if ( is_user_logged_in() && bp_blog_signup_enabled() ) {
-			$title = '<a class="button bp-title-button" href="' . trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() ) . '">' . __( 'Blogs', 'buddypress' ) . '</a>&nbsp;' . __( 'Create a Blog', 'buddypress' );
+			$title = '<a class="button bp-title-button" href="' . trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() ) . '">' . __( 'Sites', 'buddypress' ) . '</a>&nbsp;' . __( 'Create a Site', 'buddypress' );
 		} else {
-			$title = __( 'Blogs', 'buddypress' );
+			$title = __( 'Sites', 'buddypress' );
 		}
 
 		bp_theme_compat_reset_post( array(
@@ -206,18 +214,18 @@ class BP_Blogs_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => 'bp_group',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
 
 	/**
-	 * Filter the_content with the create screen template part
+	 * Filter the_content with the create screen template part.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function create_content() {
-		bp_buffer_template_part( 'blogs/create' );
+		return bp_buffer_template_part( 'blogs/create', null, false );
 	}
 }
 new BP_Blogs_Theme_Compat();
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-template.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-template.php
index 636d5253107d804a6c825fb5af27723e6b53c13e..7efaff03437d545585301f5393e78578e2044acf 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-template.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-template.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Blogs Template Tags
+ * BuddyPress Blogs Template Tags.
  *
  * @package BuddyPress
  * @subpackage BlogsTemplate
@@ -11,11 +11,9 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Output the blogs component slug
+ * Output the blogs component slug.
  *
- * @package BuddyPress
- * @subpackage BlogsTemplate
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_blogs_slug()
  */
@@ -23,22 +21,20 @@ function bp_blogs_slug() {
 	echo bp_get_blogs_slug();
 }
 	/**
-	 * Return the blogs component slug
+	 * Return the blogs component slug.
 	 *
-	 * @package BuddyPress
-	 * @subpackage BlogsTemplate
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @return string The 'blogs' slug.
 	 */
 	function bp_get_blogs_slug() {
 		return apply_filters( 'bp_get_blogs_slug', buddypress()->blogs->slug );
 	}
 
 /**
- * Output the blogs component root slug
+ * Output the blogs component root slug.
  *
- * @package BuddyPress
- * @subpackage BlogsTemplate
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_blogs_root_slug()
  */
@@ -46,69 +42,155 @@ function bp_blogs_root_slug() {
 	echo bp_get_blogs_root_slug();
 }
 	/**
-	 * Return the blogs component root slug
+	 * Return the blogs component root slug.
+	 *
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @package BuddyPress
-	 * @subpackage BlogsTemplate
-	 * @since BuddyPress (1.5)
+	 * @return string The 'blogs' root slug.
 	 */
 	function bp_get_blogs_root_slug() {
 		return apply_filters( 'bp_get_blogs_root_slug', buddypress()->blogs->root_slug );
 	}
 
 /**
- * Output blog directory permalink
+ * Output blog directory permalink.
+ *
+ * @since BuddyPress (1.5.0)
  *
- * @package BuddyPress
- * @subpackage BlogsTemplate
- * @since BuddyPress (1.5)
  * @uses bp_get_blogs_directory_permalink()
  */
 function bp_blogs_directory_permalink() {
 	echo bp_get_blogs_directory_permalink();
 }
 	/**
-	 * Return blog directory permalink
+	 * Return blog directory permalink.
+	 *
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @package BuddyPress
-	 * @subpackage BlogsTemplate
-	 * @since BuddyPress (1.5)
 	 * @uses apply_filters()
-	 * @uses traisingslashit()
+	 * @uses trailingslashit()
 	 * @uses bp_get_root_domain()
 	 * @uses bp_get_blogs_root_slug()
-	 * @return string
+	 * @return string The URL of the Blogs directory.
 	 */
 	function bp_get_blogs_directory_permalink() {
 		return apply_filters( 'bp_get_blogs_directory_permalink', trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() ) );
 	}
 
-/**********************************************************************
- * Blog listing template class.
+/**
+ * The main blog template loop class.
+ *
+ * Responsible for loading a group of blogs into a loop for display.
  */
-
 class BP_Blogs_Template {
+
+	/**
+	 * The loop iterator.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $current_blog = -1;
+
+	/**
+	 * The number of blogs returned by the paged query.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $blog_count;
+
+	/**
+	 * Array of blogs located by the query..
+	 *
+	 * @access public
+	 * @var array
+	 */
 	var $blogs;
+
+	/**
+	 * The blog object currently being iterated on.
+	 *
+	 * @access public
+	 * @var object
+	 */
 	var $blog;
 
+	/**
+	 * A flag for whether the loop is currently being iterated.
+	 *
+	 * @access public
+	 * @var bool
+	 */
 	var $in_the_loop;
 
+	/**
+	 * The page number being requested.
+	 *
+	 * @access public
+	 * @var public
+	 */
 	var $pag_page;
+
+	/**
+	 * The number of items being requested per page.
+	 *
+	 * @access public
+	 * @var public
+	 */
 	var $pag_num;
+
+	/**
+	 * An HTML string containing pagination links.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $pag_links;
+
+	/**
+	 * The total number of blogs matching the query parameters.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $total_blog_count;
 
-	function __construct( $type, $page, $per_page, $max, $user_id, $search_terms, $page_arg = 'bpage' ) {
+	/**
+	 * Constructor method.
+	 *
+	 * @see BP_Blogs_Blog::get() for a description of parameters.
+	 *
+	 * @param string $type See {@link BP_Blogs_Blog::get()}.
+	 * @param string $page See {@link BP_Blogs_Blog::get()}.
+	 * @param string $per_page See {@link BP_Blogs_Blog::get()}.
+	 * @param string $max See {@link BP_Blogs_Blog::get()}.
+	 * @param string $user_id See {@link BP_Blogs_Blog::get()}.
+	 * @param string $search_terms See {@link BP_Blogs_Blog::get()}.
+	 * @param string $page_arg The string used as a query parameter in
+	 *        pagination links. Default: 'bpage'.
+	 * @param bool $update_meta_cache Whether to pre-fetch metadata for
+	 *        queried blogs.
+	 * @param array $include_blog_ids Array of blog IDs to include.
+	 */
+	function __construct( $type, $page, $per_page, $max, $user_id, $search_terms, $page_arg = 'bpage', $update_meta_cache = true, $include_blog_ids = false ) {
 
 		$this->pag_page = isset( $_REQUEST[$page_arg] ) ? intval( $_REQUEST[$page_arg] ) : $page;
 		$this->pag_num = isset( $_REQUEST['num'] ) ? intval( $_REQUEST['num'] ) : $per_page;
 
-		if ( isset( $_REQUEST['letter'] ) && '' != $_REQUEST['letter'] )
+		if ( isset( $_REQUEST['letter'] ) && '' != $_REQUEST['letter'] ) {
 			$this->blogs = BP_Blogs_Blog::get_by_letter( $_REQUEST['letter'], $this->pag_num, $this->pag_page );
-		else
-			$this->blogs = bp_blogs_get_blogs( array( 'type' => $type, 'per_page' => $this->pag_num, 'page' => $this->pag_page, 'user_id' => $user_id, 'search_terms' => $search_terms ) );
+		} else {
+			$this->blogs = bp_blogs_get_blogs( array(
+				'type'              => $type,
+				'per_page'          => $this->pag_num,
+				'page'              => $this->pag_page,
+				'user_id'           => $user_id,
+				'search_terms'      => $search_terms,
+				'update_meta_cache' => $update_meta_cache,
+				'include_blog_ids'  => $include_blog_ids,
+			) );
+		}
 
 		if ( !$max || $max >= (int) $this->blogs['total'] )
 			$this->total_blog_count = (int) $this->blogs['total'];
@@ -140,6 +222,13 @@ class BP_Blogs_Template {
 		}
 	}
 
+	/**
+	 * Whether there are blogs available in the loop.
+	 *
+	 * @see bp_has_blogs()
+	 *
+	 * @return bool True if there are items in the loop, otherwise false.
+	 */
 	function has_blogs() {
 		if ( $this->blog_count )
 			return true;
@@ -147,6 +236,11 @@ class BP_Blogs_Template {
 		return false;
 	}
 
+	/**
+	 * Set up the next blog and iterate index.
+	 *
+	 * @return object The next blog to iterate over.
+	 */
 	function next_blog() {
 		$this->current_blog++;
 		$this->blog = $this->blogs[$this->current_blog];
@@ -154,6 +248,9 @@ class BP_Blogs_Template {
 		return $this->blog;
 	}
 
+	/**
+	 * Rewind the blogs and reset blog index.
+	 */
 	function rewind_blogs() {
 		$this->current_blog = -1;
 		if ( $this->blog_count > 0 ) {
@@ -161,6 +258,17 @@ class BP_Blogs_Template {
 		}
 	}
 
+	/**
+	 * Whether there are blogs left in the loop to iterate over.
+	 *
+	 * This method is used by {@link bp_blogs()} as part of the while loop
+	 * that controls iteration inside the blogs loop, eg:
+	 *     while ( bp_blogs() ) { ...
+	 *
+	 * @see bp_blogs()
+	 *
+	 * @return bool True if there are more blogs to show, otherwise false.
+	 */
 	function blogs() {
 		if ( $this->current_blog + 1 < $this->blog_count ) {
 			return true;
@@ -174,6 +282,15 @@ class BP_Blogs_Template {
 		return false;
 	}
 
+	/**
+	 * Set up the current blog inside the loop.
+	 *
+	 * Used by {@link bp_the_blog()} to set up the current blog data while
+	 * looping, so that template tags used during that iteration make
+	 * reference to the current blog.
+	 *
+	 * @see bp_the_blog()
+	 */
 	function the_blog() {
 
 		$this->in_the_loop = true;
@@ -184,12 +301,52 @@ class BP_Blogs_Template {
 	}
 }
 
+/**
+ * Rewind the blogs and reset blog index.
+ */
 function bp_rewind_blogs() {
 	global $blogs_template;
 
 	$blogs_template->rewind_blogs();
 }
 
+/**
+ * Initialize the blogs loop.
+ *
+ * Based on the $args passed, bp_has_blogs() populates the $blogs_template
+ * global, enabling the use of BuddyPress templates and template functions to
+ * display a list of activity items.
+ *
+ * @global object $blogs_template {@link BP_Blogs_Template}
+ *
+ * @param array $args {
+ *     Arguments for limiting the contents of the blogs loop. Most arguments
+ *     are in the same format as {@link BP_Blogs_Blog::get()}. However, because
+ *     the format of the arguments accepted here differs in a number of ways,
+ *     and because bp_has_blogs() determines some default arguments in a
+ *     dynamic fashion, we list all accepted arguments here as well.
+ *
+ *     Arguments can be passed as an associative array, or as a URL query
+ *     string (eg, 'user_id=4&per_page=3').
+ *
+ *     @type int $page Which page of results to fetch. Using page=1 without
+ *           per_page will result in no pagination. Default: 1.
+ *     @type int|bool $per_page Number of results per page. Default: 20.
+ *     @type string $page_arg The string used as a query parameter in
+ *           pagination links. Default: 'bpage'.
+ *     @type int|bool $max Maximum number of results to return.
+ *           Default: false (unlimited).
+ *     @type string $type The order in which results should be fetched.
+ *	     'active', 'alphabetical', 'newest', or 'random'.
+ *     @type array $include_blog_ids Array of blog IDs to limit results to.
+ *     @type string $sort 'ASC' or 'DESC'. Default: 'DESC'.
+ *     @type string $search_terms Limit results by a search term. Default: null.
+ *     @type int $user_id The ID of the user whose blogs should be retrieved.
+ *           When viewing a user profile page, 'user_id' defaults to the ID of
+ *           the displayed user. Otherwise the default is false.
+ * }
+ * @return bool Returns true when blogs are found, otherwise false.
+ */
 function bp_has_blogs( $args = '' ) {
 	global $blogs_template;
 
@@ -207,18 +364,20 @@ function bp_has_blogs( $args = '' ) {
 		$user_id = bp_displayed_user_id();
 
 	$defaults = array(
-		'type'         => $type,
-		'page'         => 1,
-		'per_page'     => 20,
-		'max'          => false,
+		'type'              => $type,
+		'page'              => 1,
+		'per_page'          => 20,
+		'max'               => false,
 
-		'page_arg'     => 'bpage',        // See https://buddypress.trac.wordpress.org/ticket/3679
+		'page_arg'          => 'bpage',        // See https://buddypress.trac.wordpress.org/ticket/3679
 
-		'user_id'      => $user_id,       // Pass a user_id to limit to only blogs this user has higher than subscriber access to
-		'search_terms' => $search_terms   // Pass search terms to filter on the blog title or description.
+		'user_id'           => $user_id,       // Pass a user_id to limit to only blogs this user has higher than subscriber access to
+		'include_blog_ids'  => false,
+		'search_terms'      => $search_terms,  // Pass search terms to filter on the blog title or description.
+		'update_meta_cache' => true,
 	);
 
-	$r = wp_parse_args( $args, $defaults );
+	$r = bp_parse_args( $args, $defaults, 'has_blogs' );
 	extract( $r );
 
 	if ( is_null( $search_terms ) ) {
@@ -234,22 +393,41 @@ function bp_has_blogs( $args = '' ) {
 		}
 	}
 
-	$blogs_template = new BP_Blogs_Template( $type, $page, $per_page, $max, $user_id, $search_terms, $page_arg );
+	$blogs_template = new BP_Blogs_Template( $type, $page, $per_page, $max, $user_id, $search_terms, $page_arg, $update_meta_cache, $include_blog_ids );
 	return apply_filters( 'bp_has_blogs', $blogs_template->has_blogs(), $blogs_template );
 }
 
+/**
+ * Determine if there are still blogs left in the loop.
+ *
+ * @global object $blogs_template {@link BP_Blogs_Template}
+ *
+ * @return bool Returns true when blogs are found.
+ */
 function bp_blogs() {
 	global $blogs_template;
 
 	return $blogs_template->blogs();
 }
 
+/**
+ * Get the current blog object in the loop.
+ *
+ * @global object $blogs_template {@link BP_Blogs_Template}
+ *
+ * @return object The current blog within the loop.
+ */
 function bp_the_blog() {
 	global $blogs_template;
 
 	return $blogs_template->the_blog();
 }
 
+/**
+ * Output the blogs pagination count.
+ *
+ * @global object $blogs_template {@link BP_Blogs_Template}
+ */
 function bp_blogs_pagination_count() {
 	global $blogs_template;
 
@@ -258,21 +436,62 @@ function bp_blogs_pagination_count() {
 	$to_num    = bp_core_number_format( ( $start_num + ( $blogs_template->pag_num - 1 ) > $blogs_template->total_blog_count ) ? $blogs_template->total_blog_count : $start_num + ( $blogs_template->pag_num - 1 ) );
 	$total     = bp_core_number_format( $blogs_template->total_blog_count );
 
-	echo sprintf( __( 'Viewing site %1$s to %2$s (of %3$s sites)', 'buddypress' ), $from_num, $to_num, $total );
+	echo sprintf( _n( 'Viewing site %1$s to %2$s (of %3$s site)', 'Viewing site %1$s to %2$s (of %3$s sites)', $total, 'buddypress' ), $from_num, $to_num, $total );
 }
 
+/**
+ * Output the blogs pagination links.
+ */
 function bp_blogs_pagination_links() {
 	echo bp_get_blogs_pagination_links();
 }
+	/**
+	 * Return the blogs pagination links.
+	 *
+	 * @global object $blogs_template {@link BP_Blogs_Template}
+	 *
+	 * @return string HTML pagination links.
+	 */
 	function bp_get_blogs_pagination_links() {
 		global $blogs_template;
 
 		return apply_filters( 'bp_get_blogs_pagination_links', $blogs_template->pag_links );
 	}
 
+/**
+ * Output a blog's avatar.
+ *
+ * @see bp_get_blog_avatar() for description of arguments.
+ *
+ * @param array $args See {@link bp_get_blog_avatar()}.
+ */
 function bp_blog_avatar( $args = '' ) {
 	echo bp_get_blog_avatar( $args );
 }
+	/**
+	 * Get a blog's avatar.
+	 *
+	 * At the moment, blog avatars are simply the user avatars of the blog
+	 * admin. Filter 'bp_get_blog_avatar_' . $blog_id to customize.
+	 *
+	 * @see bp_core_fetch_avatar() For a description of arguments and
+	 *      return values.
+	 *
+	 * @param array $args  {
+	 *     Arguments are listed here with an explanation of their defaults.
+	 *     For more information about the arguments, see
+	 *     {@link bp_core_fetch_avatar()}.
+	 *     @type string $alt Default: 'Profile picture of site author
+	 *           [user name]'.
+	 *     @type string $class Default: 'avatar'.
+	 *     @type string $type Default: 'full'.
+	 *     @type int|bool $width Default: false.
+	 *     @type int|bool $height Default: false.
+	 *     @type bool $id Currently unused.
+	 *     @type bool $no_grav Default: false.
+	 * }
+	 * @return string User avatar string.
+	 */
 	function bp_get_blog_avatar( $args = '' ) {
 		global $blogs_template;
 
@@ -321,9 +540,17 @@ function bp_blog_permalink() {
 		return apply_filters( 'bp_get_blog_permalink', $permalink );
 	}
 
+/**
+ * Output the name of the current blog in the loop.
+ */
 function bp_blog_name() {
 	echo bp_get_blog_name();
 }
+	/**
+	 * Return the name of the current blog in the loop.
+	 *
+	 * @return string The name of the current blog in the loop.
+	 */
 	function bp_get_blog_name() {
 		global $blogs_template;
 
@@ -331,18 +558,19 @@ function bp_blog_name() {
 	}
 
 /**
- * Outputs the blog ID
+ * Output the ID of the current blog in the loop.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_blog_id() {
 	echo bp_get_blog_id();
 }
 	/**
-	 * Returns the blog ID
+	 * Return the ID of the current blog in the loop.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @return int
-	 * @since BuddyPress (1.7)
+	 * @return int ID of the current blog in the loop.
 	 */
 	function bp_get_blog_id() {
 		global $blogs_template;
@@ -350,30 +578,39 @@ function bp_blog_id() {
 		return apply_filters( 'bp_get_blog_id', $blogs_template->blog->blog_id );
 	}
 
+/**
+ * Output the description of the current blog in the loop.
+ */
 function bp_blog_description() {
 	echo apply_filters( 'bp_blog_description', bp_get_blog_description() );
 }
+	/**
+	 * Return the description of the current blog in the loop.
+	 *
+	 * @return string Description of the current blog in the loop.
+	 */
 	function bp_get_blog_description() {
 		global $blogs_template;
 
 		return apply_filters( 'bp_get_blog_description', $blogs_template->blog->description );
 	}
 
-
 /**
- * Output the row class of a site
+ * Output the row class of the current blog in the loop.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_blog_class() {
 	echo bp_get_blog_class();
 }
 	/**
-	 * Return the row class of a site
+	 * Return the row class of the current blog in the loop.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
 	 * @global BP_Blogs_Template $blogs_template
-	 * @return string Row class of the site
-	 * @since BuddyPress (1.7)
+	 *
+	 * @return string Row class of the site.
 	 */
 	function bp_get_blog_class() {
 		global $blogs_template;
@@ -394,18 +631,34 @@ function bp_blog_class() {
 		return $retval;
 	}
 
+/**
+ * Output the last active date of the current blog in the loop.
+ */
 function bp_blog_last_active() {
 	echo bp_get_blog_last_active();
 }
+	/**
+	 * Return the last active date of the current blog in the loop.
+	 *
+	 * @return string Last active date.
+	 */
 	function bp_get_blog_last_active() {
 		global $blogs_template;
 
 		return apply_filters( 'bp_blog_last_active', bp_core_get_last_activity( $blogs_template->blog->last_activity, __( 'active %s', 'buddypress' ) ) );
 	}
 
+/**
+ * Output the latest post from the current blog in the loop.
+ */
 function bp_blog_latest_post() {
 	echo bp_get_blog_latest_post();
 }
+	/**
+	 * Return the latest post from the current blog in the loop.
+	 *
+	 * @return string $retval String of the form 'Latest Post: [link to post]'.
+	 */
 	function bp_get_blog_latest_post() {
 		global $blogs_template;
 
@@ -418,9 +671,9 @@ function bp_blog_latest_post() {
 	}
 
 /**
- * Prints this site's latest article's title
+ * Output the title of the latest post on the current blog in the loop.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
  * @see bp_get_blog_latest_post_title()
  */
@@ -428,12 +681,13 @@ function bp_blog_latest_post_title() {
 	echo bp_get_blog_latest_post_title();
 }
 	/**
-	 * Returns this site's latest article's title
+	 * Return the title of the latest post on the current blog in the loop.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 *
 	 * @global BP_Blogs_Template
-	 * @return string
+	 *
+	 * @return string Post title.
 	 */
 	function bp_get_blog_latest_post_title() {
 		global $blogs_template;
@@ -447,20 +701,23 @@ function bp_blog_latest_post_title() {
 	}
 
 /**
- * Prints this site's latest article's permalink
+ * Output the permalink of the latest post on the current blog in the loop.
+ *
+ * @since BuddyPress (1.7.0)
  *
  * @see bp_get_blog_latest_post_title()
- * @since BuddyPress (1.7)
  */
 function bp_blog_latest_post_permalink() {
 	echo bp_get_blog_latest_post_permalink();
 }
 	/**
-	 * Returns this site's latest article's permalink
+	 * Return the permalink of the latest post on the current blog in the loop.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
 	 * @global BP_Blogs_Template
-	 * @return string
-	 * @since BuddyPress (1.7)
+	 *
+	 * @return string URL of the blog's latest post.
 	 */
 	function bp_get_blog_latest_post_permalink() {
 		global $blogs_template;
@@ -474,9 +731,9 @@ function bp_blog_latest_post_permalink() {
 	}
 
 /**
- * Prints this site's latest article's content
+ * Output the content of the latest post on the current blog in the loop.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
  * @uses bp_get_blog_latest_post_content()
  */
@@ -484,12 +741,13 @@ function bp_blog_latest_post_content() {
 	echo bp_get_blog_latest_post_content();
 }
 	/**
-	 * Returns this site's latest article's content
+	 * Return the content of the latest post on the current blog in the loop.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 *
 	 * @global BP_Blogs_Template
-	 * @return string
+	 *
+	 * @return string Content of the blog's latest post.
 	 */
 	function bp_get_blog_latest_post_content() {
 		global $blogs_template;
@@ -503,24 +761,27 @@ function bp_blog_latest_post_content() {
 	}
 
 /**
- * Prints this site's latest article's featured image
+ * Output the featured image of the latest post on the current blog in the loop.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
+ * @see bp_get_blog_latest_post_content() For description of parameters.
  *
- * @param string $size Image version to return. Either "thumbnail", "medium", "large", "post-thumbnail".
- * @see bp_get_blog_latest_post_content()
+ * @param string $size See {@link bp_get_blog_latest_post_featured_image()}.
  */
 function bp_blog_latest_post_featured_image( $size = 'thumbnail' ) {
 	echo bp_get_blog_latest_post_featured_image( $size );
 }
 	/**
-	 * Returns this site's latest article's featured image
+	 * Return the featured image of the latest post on the current blog in the loop.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 *
 	 * @global BP_Blogs_Template
-	 * @param string $size Image version to return. Either "thumbnail", "medium", "large", "post-thumbnail".
-	 * @return string
+	 *
+	 * @param string $size Image version to return. 'thumbnail', 'medium',
+	 *        'large', or 'post-thumbnail'. Default: 'thumbnail'.
+	 * @return string URL of the image.
 	 */
 	function bp_get_blog_latest_post_featured_image( $size = 'thumbnail' ) {
 		global $blogs_template;
@@ -536,9 +797,12 @@ function bp_blog_latest_post_featured_image( $size = 'thumbnail' ) {
 /**
  * Does the latest blog post have a featured image?
  *
- * @param string $size Image version to check for. Either "thumbnail", "medium", "large", "post-thumbnail".
- * @return bool
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @param string $size Image version to return. 'thumbnail', 'medium', 'large',
+ *        or 'post-thumbnail'. Default: 'thumbnail'.
+ * @return bool True if the latest blog post from the current blog has a
+ *         featured image of the given size.
  */
 function bp_blog_latest_post_has_featured_image( $thumbnail = 'thumbnail' ) {
 	$image  = bp_get_blog_latest_post_featured_image( $thumbnail );
@@ -546,6 +810,13 @@ function bp_blog_latest_post_has_featured_image( $thumbnail = 'thumbnail' ) {
 	return apply_filters( 'bp_blog_latest_post_has_featured_image', ! empty( $image ), $thumbnail, $image );
 }
 
+/**
+ * Output hidden fields to help with form submissions in Sites directory.
+ *
+ * This function detects whether 's', 'letter', or 'blogs_search' requests are
+ * currently being made (as in a URL parameter), and creates corresponding
+ * hidden fields.
+ */
 function bp_blog_hidden_fields() {
 	if ( isset( $_REQUEST['s'] ) )
 		echo '<input type="hidden" id="search_terms" value="' . esc_attr( $_REQUEST['s'] ). '" name="search_terms" />';
@@ -557,25 +828,52 @@ function bp_blog_hidden_fields() {
 		echo '<input type="hidden" id="search_terms" value="' . esc_attr( $_REQUEST['blogs_search'] ) . '" name="search_terms" />';
 }
 
+/**
+ * Output the total number of blogs on the site.
+ */
 function bp_total_blog_count() {
 	echo bp_get_total_blog_count();
 }
+	/**
+	 * Return the total number of blogs on the site.
+	 *
+	 * @return int Total number of blogs.
+	 */
 	function bp_get_total_blog_count() {
 		return apply_filters( 'bp_get_total_blog_count', bp_blogs_total_blogs() );
 	}
 	add_filter( 'bp_get_total_blog_count', 'bp_core_number_format' );
 
+/**
+ * Output the total number of blogs for a given user.
+ *
+ * @param int $user_id ID of the user.
+ */
 function bp_total_blog_count_for_user( $user_id = 0 ) {
 	echo bp_get_total_blog_count_for_user( $user_id );
 }
+	/**
+	 * Return the total number of blogs for a given user.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @return int Total number of blogs for the user.
+	 */
 	function bp_get_total_blog_count_for_user( $user_id = 0 ) {
 		return apply_filters( 'bp_get_total_blog_count_for_user', bp_blogs_total_blogs_for_user( $user_id ) );
 	}
 	add_filter( 'bp_get_total_blog_count_for_user', 'bp_core_number_format' );
 
 
-/* Blog registration template tags */
+/** Blog Registration ********************************************************/
 
+/**
+ * Checks whether blog creation is enabled.
+ *
+ * Returns true when blog creation is enabled for logged-in users only, or
+ * when it's enabled for new registrations.
+ *
+ * @return bool True if blog registration is enabled.
+ */
 function bp_blog_signup_enabled() {
 	global $bp;
 
@@ -589,6 +887,14 @@ function bp_blog_signup_enabled() {
 	return true;
 }
 
+/**
+ * Output the wrapper markup for the blog signup form.
+ *
+ * @param string $blogname Optional. The default blog name (path or domain).
+ * @param string $blog_title Optional. The default blog title.
+ * @param string|WP_Error Optional. The WP_Error object returned by a previous
+ *        submission attempt.
+ */
 function bp_show_blog_signup_form($blogname = '', $blog_title = '', $errors = '') {
 	global $current_user;
 
@@ -620,7 +926,7 @@ function bp_show_blog_signup_form($blogname = '', $blog_title = '', $errors = ''
 
 			<?php bp_blogs_signup_blog($blogname, $blog_title, $errors); ?>
 			<p>
-				<input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Create Site', 'buddypress') ?>" />
+				<input id="submit" type="submit" name="submit" class="submit" value="<?php esc_attr_e('Create Site', 'buddypress') ?>" />
 			</p>
 
 			<?php wp_nonce_field( 'bp_blog_signup_form' ) ?>
@@ -629,6 +935,14 @@ function bp_show_blog_signup_form($blogname = '', $blog_title = '', $errors = ''
 	}
 }
 
+/**
+ * Output the input fields for the blog creation form.
+ *
+ * @param string $blogname Optional. The default blog name (path or domain).
+ * @param string $blog_title Optional. The default blog title.
+ * @param string|WP_Error Optional. The WP_Error object returned by a previous
+ *        submission attempt.
+ */
 function bp_blogs_signup_blog( $blogname = '', $blog_title = '', $errors = '' ) {
 	global $current_site;
 
@@ -693,19 +1007,19 @@ function bp_blogs_signup_blog( $blogname = '', $blog_title = '', $errors = '' )
 }
 
 /**
- * Echo the value of bp_blogs_get_subdomain_base()
+ * Output the base URL for subdomain installations of WordPress Multisite.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 function bp_blogs_subdomain_base() {
 	echo bp_blogs_get_subdomain_base();
 }
 	/**
-	 * Return the base URL to be displayed when a user chooses an address for a new blog, on
-	 * a subdomain installation of WordPress MS
+	 * Return the base URL for subdomain installations of WordPress Multisite.
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @since BuddyPress (1.6)
-	 * @return string The base URL - eg, 'example.com' for site_url() example.com or www.example.com
+	 * @return string The base URL - eg, 'example.com' for site_url() example.com or www.example.com.
 	 */
 	function bp_blogs_get_subdomain_base() {
 		global $current_site;
@@ -713,6 +1027,13 @@ function bp_blogs_subdomain_base() {
 		return apply_filters( 'bp_blogs_subdomain_base', preg_replace( '|^www\.|', '', $current_site->domain ) . $current_site->path );
 	}
 
+/**
+ * Process a blog registration submission.
+ *
+ * Passes submitted values to {@link wpmu_create_blog()}.
+ *
+ * @return bool True on success, false on failure.
+ */
 function bp_blogs_validate_blog_signup() {
 	global $wpdb, $current_user, $blogname, $blog_title, $errors, $domain, $path, $current_site;
 
@@ -747,6 +1068,13 @@ function bp_blogs_validate_blog_signup() {
 	return true;
 }
 
+/**
+ * Validate a blog creation submission.
+ *
+ * Essentially, a wrapper for {@link wpmu_validate_blog_signup()}.
+ *
+ * @return array Contains the new site data and error messages.
+ */
 function bp_blogs_validate_blog_form() {
 	$user = '';
 	if ( is_user_logged_in() )
@@ -755,6 +1083,16 @@ function bp_blogs_validate_blog_form() {
 	return wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title'], $user);
 }
 
+/**
+ * Display a message after successful blog registration.
+ *
+ * @param string $domain The new blog's domain.
+ * @param string $path The new blog's path.
+ * @param string $blog_title The new blog's title.
+ * @param string $user_name The user name of the user who created the blog. Unused.
+ * @param string $user_email The email of the user who created the blog. Unused.
+ * @param string|array $meta Meta values associated with the new blog. Unused.
+ */
 function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name, $user_email = '', $meta = '' ) {
 	$protocol = is_ssl() ? 'https://' : 'http://';
 	$blog_url = $protocol . $domain . $path; ?>
@@ -768,11 +1106,19 @@ function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name,
 	do_action('signup_finished');
 }
 
+/**
+ * Output a "Create a Site" link for users viewing their own profiles.
+ */
 function bp_create_blog_link() {
 	if ( bp_is_my_profile() )
 		echo apply_filters( 'bp_create_blog_link', '<a href="' . bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/create/">' . __( 'Create a Site', 'buddypress' ) . '</a>' );
 }
 
+/**
+ * Output navigation tabs for a user Blogs page.
+ *
+ * Currently unused by BuddyPress.
+ */
 function bp_blogs_blog_tabs() {
 
 	// Don't show these tabs on a user's own profile
@@ -791,36 +1137,88 @@ function bp_blogs_blog_tabs() {
 	do_action( 'bp_blogs_blog_tabs' );
 }
 
+/**
+ * Output the blog directory search form.
+ */
 function bp_directory_blogs_search_form() {
-
 	$default_search_value = bp_get_search_default_text();
-	$search_value         = !empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : $default_search_value; ?>
+	$search_value         = !empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : $default_search_value;
 
-	<form action="" method="get" id="search-blogs-form">
-		<label><input type="text" name="s" id="blogs_search" placeholder="<?php echo esc_attr( $search_value ) ?>" /></label>
-		<input type="submit" id="blogs_search_submit" name="blogs_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
-	</form>
+	$search_form_html = '<form action="" method="get" id="search-blogs-form">
+		<label><input type="text" name="s" id="blogs_search" placeholder="'. esc_attr( $search_value ) .'" /></label>
+		<input type="submit" id="blogs_search_submit" name="blogs_search_submit" value="' . __( 'Search', 'buddypress' ) . '" />
+	</form>';
 
-<?php
+	echo apply_filters( 'bp_directory_blogs_search_form', $search_form_html );
+}
+
+/**
+ * Output the Create a Site button.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_blog_create_button() {
+	echo bp_get_blog_create_button();
 }
+	/**
+	 * Get the Create a Site button.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @return string
+	 */
+	function bp_get_blog_create_button() {
+		if ( ! is_user_logged_in() ) {
+			return false;
+		}
+
+		if ( ! bp_blog_signup_enabled() ) {
+			return false;
+		}
+
+		$button_args = array(
+			'id'         => 'create_blog',
+			'component'  => 'blogs',
+			'link_text'  => __( 'Create a Site', 'buddypress' ),
+			'link_title' => __( 'Create a Site', 'buddypress' ),
+			'link_class' => 'button blog-create bp-title-button',
+			'link_href'  => trailingslashit( bp_get_root_domain() ) . trailingslashit( bp_get_blogs_root_slug() ) . trailingslashit( 'create' ),
+			'wrapper'    => false,
+		);
+
+		return bp_get_button( apply_filters( 'bp_get_blog_create_button', $button_args ) );
+	}
 
 /**
- * bp_blogs_visit_blog_button()
+ * Output button for visiting a blog in a loop.
  *
- * Output button for visiting a blog in a loop
+ * @see bp_get_blogs_visit_blog_button() for description of arguments.
  *
- * @param array $args Custom button properties
+ * @param array $args See {@link bp_get_blogs_visit_blog_button()}.
  */
 function bp_blogs_visit_blog_button( $args = '' ) {
 	echo bp_get_blogs_visit_blog_button( $args );
 }
 	/**
-	 * bp_get_blogs_visit_blog_button()
+	 * Return button for visiting a blog in a loop.
 	 *
-	 * Return button for visiting a blog in a loop
+	 * @see BP_Button for a complete description of arguments and return
+	 *      value.
 	 *
-	 * @param array $args Custom button properties
-	 * @return string
+	 * @param array $args {
+	 *     Arguments are listed below, with their default values. For a
+	 *     complete description of arguments, see {@link BP_Button}.
+	 *     @type string $id Default: 'visit_blog'.
+	 *     @type string $component Default: 'blogs'.
+	 *     @type bool $must_be_logged_in Default: false.
+	 *     @type bool $block_self Default: false.
+	 *     @type string $wrapper_class Default: 'blog-button visit'.
+	 *     @type string $link_href Permalink of the current blog in the loop.
+	 *     @type string $link_class Default: 'blog-button visit'.
+	 *     @type string $link_text Default: 'Visit Site'.
+	 *     @type string $link_title Default: 'Visit Site'.
+	 * }
+	 * @return string The HTML for the Visit button.
 	 */
 	function bp_get_blogs_visit_blog_button( $args = '' ) {
 		$defaults = array(
@@ -840,3 +1238,57 @@ function bp_blogs_visit_blog_button( $args = '' ) {
 		// Filter and return the HTML button
 		return bp_get_button( apply_filters( 'bp_get_blogs_visit_blog_button', $button ) );
 	}
+
+/** Stats **********************************************************************/
+
+/**
+ * Display the number of blogs in user's profile.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $args before|after|user_id
+ * @uses bp_blogs_admin_get_profile_stats() to get the stats
+ */
+function bp_blogs_profile_stats( $args = '' ) {
+	echo bp_blogs_get_profile_stats( $args );
+}
+add_action( 'bp_members_admin_user_stats', 'bp_blogs_profile_stats', 9, 1 );
+
+/**
+ * Return the number of blogs in user's profile.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $args before|after|user_id
+ * @return string HTML for stats output.
+ */
+function bp_blogs_get_profile_stats( $args = '' ) {
+
+	// Parse the args
+	$r = bp_parse_args( $args, array(
+		'before'  => '<li class="bp-blogs-profile-stats">',
+		'after'   => '</li>',
+		'user_id' => bp_displayed_user_id(),
+		'blogs'   => 0,
+		'output'  => ''
+	), 'blogs_get_profile_stats' );
+
+	// Allow completely overloaded output
+	if ( is_multisite() && empty( $r['output'] ) ) {
+
+		// Only proceed if a user ID was passed
+		if ( ! empty( $r['user_id'] ) ) {
+
+			// Get the user's blogs
+			if ( empty( $r['blogs'] ) ) {
+				$r['blogs'] = absint( bp_blogs_total_blogs_for_user( $r['user_id'] ) );
+			}
+
+			// If blogs exist, show some formatted output
+			$r['output'] = $r['before'] . sprintf( _n( '%s site', '%s sites', $r['blogs'], 'buddypress' ), '<strong>' . $r['blogs'] . '</strong>' ) . $r['after'];
+		}
+	}
+
+	// Filter and return
+	return apply_filters( 'bp_blogs_get_profile_stats', $r['output'], $r );
+}
diff --git a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-widgets.php b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-widgets.php
index fe161f0e3a06c7c04c4dd2e5e2752ea8b20326ad..a5ad4eeac0ef6ffadeb8ca8d9454d6f2e3737357 100644
--- a/wp-content/plugins/buddypress/bp-blogs/bp-blogs-widgets.php
+++ b/wp-content/plugins/buddypress/bp-blogs/bp-blogs-widgets.php
@@ -10,7 +10,9 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
-// @todo not use create_function()
+/**
+ * Register the widgets for the Blogs component.
+ */
 function bp_blogs_register_widgets() {
 	global $wpdb;
 
@@ -24,6 +26,9 @@ add_action( 'bp_register_widgets', 'bp_blogs_register_widgets' );
  */
 class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
 
+	/**
+	 * Constructor method.
+	 */
 	function __construct() {
 		$widget_ops = array(
 			'description' => __( 'A list of recently published posts from across your network.', 'buddypress' ),
@@ -32,6 +37,14 @@ class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
 		parent::__construct( false, $name = _x( '(BuddyPress) Recent Networkwide Posts', 'widget name', 'buddypress' ), $widget_ops );
 	}
 
+	/**
+	 * Display the networkwide posts widget.
+	 *
+	 * @see WP_Widget::widget() for description of parameters.
+	 *
+	 * @param array $args Widget arguments.
+	 * @param array $instance Widget settings, as saved by the user.
+	 */
 	function widget( $args, $instance ) {
 
 		$title = ! empty( $instance['title'] ) ? esc_html( $instance['title'] ) : __( 'Recent Networkwide Posts', 'buddypress' );
@@ -83,6 +96,13 @@ class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
 	<?php
 	}
 
+	/**
+	 * Update the networkwide posts widget options.
+	 *
+	 * @param array $new_instance The new instance options.
+	 * @param array $old_instance The old instance options.
+	 * @return array $instance The parsed options to be saved.
+	 */
 	function update( $new_instance, $old_instance ) {
 		$instance = $old_instance;
 		$instance['title'] = strip_tags( $new_instance['title'] );
@@ -92,6 +112,11 @@ class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
 		return $instance;
 	}
 
+	/**
+	 * Output the networkwide posts widget options form.
+	 *
+	 * @param $instance Settings for this widget.
+	 */
 	function form( $instance ) {
 		$instance = wp_parse_args( (array) $instance, array(
 			'title'      => __( 'Recent Networkwide Posts', 'buddypress' ),
diff --git a/wp-content/plugins/buddypress/bp-core/admin/bp-core-actions.php b/wp-content/plugins/buddypress/bp-core/admin/bp-core-actions.php
index acbac049fa392e3fd4046f0798c01e14648a36bd..68d954209312f01411b18090610525050a4b3f91 100644
--- a/wp-content/plugins/buddypress/bp-core/admin/bp-core-actions.php
+++ b/wp-content/plugins/buddypress/bp-core/admin/bp-core-actions.php
@@ -3,9 +3,6 @@
 /**
  * BuddyPress Admin Actions
  *
- * @package BuddyPress
- * @subpackage Admin
- *
  * This file contains the actions that are used through-out BuddyPress Admin. They
  * are consolidated here to make searching for them easier, and to help developers
  * understand at a glance the order in which things occur.
@@ -15,6 +12,8 @@
  *  - BuddyPress: In {@link BuddyPress::setup_actions()} in BuddyPress.php
  *  - Admin: More in {@link bp_Admin::setup_actions()} in admin.php
  *
+ * @package BuddyPress
+ * @subpackage Admin
  * @see bp-core-actions.php
  * @see bp-core-filters.php
  */
@@ -131,13 +130,17 @@ function bp_admin_notices() {
 }
 
 /**
- * Piggy back admin_notices action
+ * Piggy back admin_enqueue_scripts action.
  *
- * @since BuddyPress (1.7)
- * @uses do_action() Calls 'bp_admin_notices'
+ * @since BuddyPress (1.7.0)
+ *
+ * @uses do_action() Calls 'bp_admin_enqueue_scripts''.
+ *
+ * @param string $hook_suffix The current admin page, passed to
+ *        'admin_enqueue_scripts'.
  */
-function bp_admin_enqueue_scripts() {
-	do_action( 'bp_admin_enqueue_scripts' );
+function bp_admin_enqueue_scripts( $hook_suffix = '' ) {
+	do_action( 'bp_admin_enqueue_scripts', $hook_suffix );
 }
 
 /**
diff --git a/wp-content/plugins/buddypress/bp-core/admin/bp-core-components.php b/wp-content/plugins/buddypress/bp-core/admin/bp-core-components.php
index e15ed3f65405dab889a888eeb841d1b31b39e02d..f05d285846b43db5215514c862f752b388450d35 100644
--- a/wp-content/plugins/buddypress/bp-core/admin/bp-core-components.php
+++ b/wp-content/plugins/buddypress/bp-core/admin/bp-core-components.php
@@ -29,7 +29,7 @@ function bp_core_admin_components_settings() {
 			<?php bp_core_admin_components_options(); ?>
 
 			<p class="submit clear">
-				<input class="button-primary" type="submit" name="bp-admin-component-submit" id="bp-admin-component-submit" value="<?php _e( 'Save Settings', 'buddypress' ) ?>"/>
+				<input class="button-primary" type="submit" name="bp-admin-component-submit" id="bp-admin-component-submit" value="<?php esc_attr_e( 'Save Settings', 'buddypress' ) ?>"/>
 			</p>
 
 			<?php wp_nonce_field( 'bp-admin-component-setup' ); ?>
@@ -58,12 +58,20 @@ function bp_core_admin_components_options() {
 		'xprofile' => array(
 			'title'       => __( 'Extended Profiles', 'buddypress' ),
 			'description' => __( 'Customize your community with fully editable profile fields that allow your users to describe themselves.', 'buddypress' )
-		)
+		),
+		'settings' => array(
+			'title'       => __( 'Account Settings', 'buddypress' ),
+			'description' => __( 'Allow your users to modify their account and notification settings directly from within their profiles.', 'buddypress' )
+		),
+		'notifications' => array(
+			'title'       => __( 'Notifications', 'buddypress' ),
+			'description' => __( 'Notify members of relevant activity with a toolbar bubble and/or via email, and allow them to customize their notification settings.', 'buddypress' )
+		),
 	);
 
 	$optional_components = bp_core_admin_get_components( 'optional' );
 	$required_components = bp_core_admin_get_components( 'required' );
-	$retired_components = bp_core_admin_get_components( 'retired' );
+	$retired_components  = bp_core_admin_get_components( 'retired'  );
 
 	// Don't show Forums component in optional components if it's disabled
 	if ( ! bp_is_active( 'forums' ) ) {
@@ -239,7 +247,7 @@ function bp_core_admin_components_settings_handler() {
 		$bp = buddypress();
 
 		// Save settings and upgrade schema
-		require_once( BP_PLUGIN_DIR . '/bp-core/admin/bp-core-schema.php' );
+		require_once( $bp->plugin_dir . '/bp-core/admin/bp-core-schema.php' );
 
 		$submitted = stripslashes_deep( $_POST['bp_components'] );
 		$bp->active_components = bp_core_admin_get_active_components_from_submitted_settings( $submitted );
@@ -254,6 +262,7 @@ function bp_core_admin_components_settings_handler() {
 
 	// Redirect
 	wp_redirect( $base_url );
+	die();
 }
 add_action( 'bp_admin_init', 'bp_core_admin_components_settings_handler' );
 
@@ -369,7 +378,11 @@ function bp_core_admin_get_components( $type = 'all' ) {
 		),
 		'activity' => array(
 			'title'       => __( 'Activity Streams', 'buddypress' ),
-			'description' => __( 'Global, personal, and group activity streams with threaded commenting, direct posting, favoriting and @mentions, all with full RSS feed and email notification support.', 'buddypress' )
+			'description' => __( 'Global, personal, and group activity streams with threaded commenting, direct posting, favoriting, and @mentions, all with full RSS feed and email notification support.', 'buddypress' )
+		),
+		'notifications' => array(
+			'title'       => __( 'Notifications', 'buddypress' ),
+			'description' => __( 'Notify members of relevant activity with a toolbar bubble and/or via email, and allow them to customize their notification settings.', 'buddypress' )
 		),
 		'groups'   => array(
 			'title'       => __( 'User Groups', 'buddypress' ),
@@ -408,5 +421,5 @@ function bp_core_admin_get_components( $type = 'all' ) {
 
 	}
 
-	return $components;
+	return apply_filters( 'bp_core_admin_get_components', $components, $type );
 }
diff --git a/wp-content/plugins/buddypress/bp-core/admin/bp-core-functions.php b/wp-content/plugins/buddypress/bp-core/admin/bp-core-functions.php
index 7e145fa3a9f17bb52cdabbe4ed9544f66e476871..4daa6ae889ed829a27e6b8e725b3e4f5bf38afde 100644
--- a/wp-content/plugins/buddypress/bp-core/admin/bp-core-functions.php
+++ b/wp-content/plugins/buddypress/bp-core/admin/bp-core-functions.php
@@ -74,11 +74,16 @@ add_action( bp_core_admin_hook(), 'bp_core_admin_backpat_menu', 999 );
  * @since BuddyPress (1.6)
  */
 function bp_core_modify_admin_menu_highlight() {
-	global $plugin_page, $submenu_file;
+	global $pagenow, $plugin_page, $submenu_file;
 
 	// This tweaks the Settings subnav menu to show only one BuddyPress menu item
 	if ( ! in_array( $plugin_page, array( 'bp-activity', 'bp-general-settings', ) ) )
 		$submenu_file = 'bp-components';
+
+	// Network Admin > Tools
+	if ( in_array( $plugin_page, array( 'bp-tools', 'available-tools' ) ) ) {
+		$submenu_file = $plugin_page;
+	}
 }
 
 /**
@@ -120,27 +125,35 @@ function bp_core_admin_backpat_page() {
  * @uses bp_is_root_blog()
  */
 function bp_core_print_admin_notices() {
-	$bp = buddypress();
 
 	// Only the super admin should see messages
-	if ( !bp_current_user_can( 'bp_moderate' ) )
+	if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 		return;
+	}
 
-	// On multisite installs, don't show on the Site Admin of a non-root blog, unless
-	// do_network_admin is overridden
-	if ( is_multisite() && bp_core_do_network_admin() && !bp_is_root_blog() )
+	// On multisite installs, don't show on a non-root blog, unless
+	// 'do_network_admin' is overridden.
+	if ( is_multisite() && bp_core_do_network_admin() && ! bp_is_root_blog() ) {
 		return;
+	}
+
+	// Get the admin notices
+	$admin_notices = buddypress()->admin->notices;
 
 	// Show the messages
-	if ( !empty( $bp->admin->notices ) ) {
-		?>
+	if ( !empty( $admin_notices ) ) : ?>
+
 		<div id="message" class="updated fade">
-		<?php foreach ( $bp->admin->notices as $notice ) : ?>
-				<p><?php echo $notice ?></p>
-		<?php endforeach ?>
+
+			<?php foreach ( $admin_notices as $notice ) : ?>
+
+				<p><?php echo $notice; ?></p>
+
+			<?php endforeach; ?>
+
 		</div>
-		<?php
-	}
+
+	<?php endif;
 }
 add_action( 'admin_notices',         'bp_core_print_admin_notices' );
 add_action( 'network_admin_notices', 'bp_core_print_admin_notices' );
@@ -157,14 +170,20 @@ add_action( 'network_admin_notices', 'bp_core_print_admin_notices' );
  *
  * @param string $notice The notice you are adding to the queue
  */
-function bp_core_add_admin_notice( $notice ) {
-	$bp = buddypress();
+function bp_core_add_admin_notice( $notice = '' ) {
+
+	// Do not add if the notice is empty
+	if ( empty( $notice ) ) {
+		return;
+	}
 
-	if ( empty( $bp->admin->notices ) ) {
-		$bp->admin->notices = array();
+	// Double check the object before referencing it
+	if ( ! isset( buddypress()->admin->notices ) ) {
+		buddypress()->admin->notices = array();
 	}
 
-	$bp->admin->notices[] = $notice;
+	// Add the notice
+	buddypress()->admin->notices[] = $notice;
 }
 
 /**
@@ -186,12 +205,24 @@ function bp_core_activation_notice() {
 	$bp = buddypress();
 
 	// Only the super admin gets warnings
-	if ( !bp_current_user_can( 'bp_moderate' ) )
+	if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 		return;
+	}
 
 	// On multisite installs, don't load on a non-root blog, unless do_network_admin is overridden
-	if ( is_multisite() && bp_core_do_network_admin() && !bp_is_root_blog() )
+	if ( is_multisite() && bp_core_do_network_admin() && !bp_is_root_blog() ) {
 		return;
+	}
+
+	// Bail if in network admin, and BuddyPress is not network activated
+	if ( is_network_admin() && ! bp_is_network_activated() ) {
+		return;
+	}
+
+	// Bail in network admin
+	if ( is_user_admin() ) {
+		return;
+	}
 
 	/**
 	 * Check to make sure that the blog setup routine has run. This can't happen during the
@@ -209,8 +240,9 @@ function bp_core_activation_notice() {
 	/**
 	 * Are pretty permalinks enabled?
 	 */
-	if ( isset( $_POST['permalink_structure'] ) )
+	if ( isset( $_POST['permalink_structure'] ) ) {
 		return;
+	}
 
 	if ( empty( $wp_rewrite->permalink_structure ) ) {
 		bp_core_add_admin_notice( sprintf( __( '<strong>BuddyPress is almost ready</strong>. You must <a href="%s">update your permalink structure</a> to something other than the default for it to work.', 'buddypress' ), admin_url( 'options-permalink.php' ) ) );
@@ -244,11 +276,14 @@ function bp_core_activation_notice() {
 			'id'   => 'register',
 			'name' => __( 'Register', 'buddypress' )
 		);
+
+		bp_core_maybe_install_signups();
 	}
 
 	// On the first admin screen after a new installation, this isn't set, so grab it to supress a misleading error message.
-	if ( empty( $bp->pages->members ) )
+	if ( empty( $bp->pages->members ) ) {
 		$bp->pages = bp_core_get_directory_pages();
+	}
 
 	foreach( $wp_page_components as $component ) {
 		if ( !isset( $bp->pages->{$component['id']} ) ) {
@@ -267,7 +302,7 @@ function bp_core_activation_notice() {
 
 	if ( !empty( $orphaned_components ) ) {
 		$admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
-		$notice    = sprintf( __( 'The following active BuddyPress Components do not have associated WordPress Pages: %2$s. <a href="%1$s" class="button-secondary">Repair</a>', 'buddypress' ), $admin_url, '<strong>' . implode( '</strong>, <strong>', $orphaned_components ) . '</strong>' );
+		$notice    = sprintf( __( 'The following active BuddyPress Components do not have associated WordPress Pages: %2$s. <a href="%1$s">Repair</a>', 'buddypress' ), $admin_url, '<strong>' . implode( '</strong>, <strong>', $orphaned_components ) . '</strong>' );
 
 		bp_core_add_admin_notice( $notice );
 	}
@@ -289,7 +324,7 @@ function bp_core_activation_notice() {
 	// If there are duplicates, post a message about them
 	if ( !empty( $dupe_names ) ) {
 		$admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
-		$notice    = sprintf( __( 'Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %2$s. <a href="%1$s" class="button-secondary">Repair</a>', 'buddypress' ), $admin_url, '<strong>' . implode( '</strong>, <strong>', $dupe_names ) . '</strong>' );
+		$notice    = sprintf( __( 'Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %2$s. <a href="%1$s">Repair</a>', 'buddypress' ), $admin_url, '<strong>' . implode( '</strong>, <strong>', $dupe_names ) . '</strong>' );
 
 		bp_core_add_admin_notice( $notice );
 	}
@@ -360,11 +395,12 @@ function bp_core_admin_tabs( $active_tab = '' ) {
 		'2' => array(
 			'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ),
 			'name' => __( 'Settings', 'buddypress' )
-		)
+		),
 	);
 
 	// If forums component is active, add additional tab
 	if ( bp_is_active( 'forums' ) && class_exists( 'BP_Forums_Component' ) ) {
+
 		// enqueue thickbox
 		wp_enqueue_script( 'thickbox' );
 		wp_enqueue_style( 'thickbox' );
@@ -375,11 +411,14 @@ function bp_core_admin_tabs( $active_tab = '' ) {
 		);
 	}
 
+	// Allow the tabs to be filtered
+	$tabs = apply_filters( 'bp_core_admin_tabs', $tabs );
+
 	// Loop through tabs and build navigation
 	foreach ( array_values( $tabs ) as $tab_data ) {
 		$is_current = (bool) ( $tab_data['name'] == $active_tab );
 		$tab_class  = $is_current ? $active_class : $idle_class;
-		$tabs_html .= '<a href="' . $tab_data['href'] . '" class="' . $tab_class . '">' . $tab_data['name'] . '</a>';
+		$tabs_html .= '<a href="' . esc_url( $tab_data['href'] ) . '" class="' . esc_attr( $tab_class ) . '">' . esc_html( $tab_data['name'] ) . '</a>';
 	}
 
 	// Output the tabs
@@ -409,7 +448,7 @@ function bp_core_add_contextual_help( $screen = '' ) {
 			// help tabs
 			$screen->add_help_tab( array(
 				'id'      => 'bp-comp-overview',
-				'title'   => __( 'Overview' ),
+				'title'   => __( 'Overview', 'buddypress' ),
 				'content' => bp_core_add_contextual_help_content( 'bp-comp-overview' ),
 			) );
 
@@ -427,7 +466,7 @@ function bp_core_add_contextual_help( $screen = '' ) {
 			// Help tabs
 			$screen->add_help_tab( array(
 				'id' => 'bp-page-overview',
-				'title' => __( 'Overview' ),
+				'title' => __( 'Overview', 'buddypress' ),
 				'content' => bp_core_add_contextual_help_content( 'bp-page-overview' ),
 			) );
 
@@ -446,7 +485,7 @@ function bp_core_add_contextual_help( $screen = '' ) {
 			// Help tabs
 			$screen->add_help_tab( array(
 				'id'      => 'bp-settings-overview',
-				'title'   => __( 'Overview' ),
+				'title'   => __( 'Overview', 'buddypress' ),
 				'content' => bp_core_add_contextual_help_content( 'bp-settings-overview' ),
 			) );
 
@@ -460,12 +499,12 @@ function bp_core_add_contextual_help( $screen = '' ) {
 			break;
 
 		// Profile fields page
-		case 'users_page_bp-profile-overview' :
+		case 'users_page_bp-profile-setup' :
 
 			// Help tabs
 			$screen->add_help_tab( array(
 				'id'      => 'bp-profile-overview',
-				'title'   => __( 'Overview' ),
+				'title'   => __( 'Overview', 'buddypress' ),
 				'content' => bp_core_add_contextual_help_content( 'bp-profile-overview' ),
 			) );
 
@@ -490,25 +529,32 @@ function bp_core_add_contextual_help_content( $tab = '' ) {
 
 	switch ( $tab ) {
 		case 'bp-comp-overview' :
-			return '<p>' . __( 'By default, all BuddyPress components are enabled. You can selectively disable any of the components by using the form. Your BuddyPress installation will continue to function. However, the features of the disabled components will no longer be accessible to anyone using the site.', 'buddypress' ) . '</p>';
+			$retval = __( 'By default, all BuddyPress components are enabled. You can selectively disable any of the components by using the form. Your BuddyPress installation will continue to function. However, the features of the disabled components will no longer be accessible to anyone using the site.', 'buddypress' );
 			break;
 
-		case'bp-page-overview' :
-			return '<p>' . __( 'BuddyPress Components use WordPress Pages for their root directory/archive pages. Here you can change the page associations for each active component.', 'buddypress' ) . '</p>';
+		case 'bp-page-overview' :
+			$retval = __( 'BuddyPress Components use WordPress Pages for their root directory/archive pages. Here you can change the page associations for each active component.', 'buddypress' );
 			break;
 
 		case 'bp-settings-overview' :
-			return '<p>' . __( 'Extra configuration settings.', 'buddypress' ) . '</p>';
+			$retval = __( 'Extra configuration settings.', 'buddypress' );
 			break;
 
 		case 'bp-profile-overview' :
-			return '<p>' . __( 'Your users will distinguish themselves through their profile page. Create relevant profile fields that will show on each users profile.</br></br>Note: Any fields in the first group will appear on the signup page.', 'buddypress' ) . '</p>';
+			$retval = __( 'Your users will distinguish themselves through their profile page. Create relevant profile fields that will show on each users profile.</br></br>Note: Any fields in the first group will appear on the signup page.', 'buddypress' );
 			break;
 
 		default:
-			return false;
+			$retval = false;
 			break;
 	}
+
+	// Wrap text in a paragraph tag
+	if ( !empty( $retval ) ) {
+		$retval = '<p>' . $retval . '</p>';
+	}
+
+	return $retval;
 }
 
 /** Separator *****************************************************************/
@@ -642,3 +688,237 @@ function bp_admin_list_table_current_bulk_action() {
 
 	return $action;
 }
+
+/** Menus *********************************************************************/
+
+/**
+ * Register meta box and associated JS for BuddyPress WP Nav Menu .
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_admin_wp_nav_menu_meta_box() {
+	if ( ! bp_is_root_blog() ) {
+		return;
+	}
+
+	add_meta_box( 'add-buddypress-nav-menu', __( 'BuddyPress', 'buddypress' ), 'bp_admin_do_wp_nav_menu_meta_box', 'nav-menus', 'side', 'default' );
+
+	add_action( 'admin_print_footer_scripts', 'bp_admin_wp_nav_menu_restrict_items' );
+}
+
+/**
+ * Build and populate the BuddyPress accordion on Appearance > Menus.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @global $nav_menu_selected_id
+ */
+function bp_admin_do_wp_nav_menu_meta_box() {
+	global $nav_menu_selected_id;
+
+	$walker = new BP_Walker_Nav_Menu_Checklist( false );
+	$args   = array( 'walker' => $walker );
+
+	$post_type_name = 'buddypress';
+
+	$tabs = array();
+
+	$tabs['loggedin']['label']  = __( 'Logged-In', 'buddypress' );
+	$tabs['loggedin']['pages']  = bp_nav_menu_get_loggedin_pages();
+
+	$tabs['loggedout']['label'] = __( 'Logged-Out', 'buddypress' );
+	$tabs['loggedout']['pages'] = bp_nav_menu_get_loggedout_pages();
+
+	?>
+
+	<div id="buddypress-menu" class="posttypediv">
+		<h4><?php _e( 'Logged-In', 'buddypress' ) ?></h4>
+		<p><?php _e( '<em>Logged-In</em> links are relative to the current user, and are not visible to visitors who are not logged in.', 'buddypress' ) ?></p>
+
+		<div id="tabs-panel-posttype-<?php echo $post_type_name; ?>-loggedin" class="tabs-panel tabs-panel-active">
+			<ul id="buddypress-menu-checklist-loggedin" class="categorychecklist form-no-clear">
+				<?php echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $tabs['loggedin']['pages'] ), 0, (object) $args );?>
+			</ul>
+		</div>
+
+		<h4><?php _e( 'Logged-Out', 'buddypress' ) ?></h4>
+		<p><?php _e( '<em>Logged-Out</em> links are not visible to users who are logged in.', 'buddypress' ) ?></p>
+
+		<div id="tabs-panel-posttype-<?php echo $post_type_name; ?>-loggedout" class="tabs-panel tabs-panel-active">
+			<ul id="buddypress-menu-checklist-loggedout" class="categorychecklist form-no-clear">
+				<?php echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $tabs['loggedout']['pages'] ), 0, (object) $args );?>
+			</ul>
+		</div>
+
+		<p class="button-controls">
+			<span class="add-to-menu">
+				<input type="submit"<?php if ( function_exists( 'wp_nav_menu_disabled_check' ) ) : wp_nav_menu_disabled_check( $nav_menu_selected_id ); endif; ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to Menu', 'buddypress' ); ?>" name="add-custom-menu-item" id="submit-buddypress-menu" />
+				<span class="spinner"></span>
+			</span>
+		</p>
+	</div><!-- /#buddypress-menu -->
+
+	<?php
+}
+
+/**
+ * Restrict various items from view if editing a BuddyPress menu.
+ *
+ * If a person is editing a BP menu item, that person should not be able to
+ * see or edit the following fields:
+ *
+ * - CSS Classes - We use the 'bp-menu' CSS class to determine if the
+ *   menu item belongs to BP, so we cannot allow manipulation of this field to
+ *   occur.
+ * - URL - This field is automatically generated by BP on output, so this
+ *   field is useless and can cause confusion.
+ *
+ * Note: These restrictions are only enforced if javascript is enabled.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_admin_wp_nav_menu_restrict_items() {
+?>
+	<script type="text/javascript">
+	jQuery( '#menu-to-edit').on( 'click', 'a.item-edit', function() {
+		var settings  = jQuery(this).closest( '.menu-item-bar' ).next( '.menu-item-settings' );
+		var css_class = settings.find( '.edit-menu-item-classes' );
+
+		if( css_class.val().indexOf( 'bp-menu' ) === 0 ) {
+			css_class.attr( 'readonly', 'readonly' );
+			settings.find( '.field-url' ).css( 'display', 'none' );
+		}
+	});
+	</script>
+<?php
+}
+
+/**
+ * Check if the signups table needs to be created.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @global $wpdb
+ */
+function bp_core_maybe_install_signups() {
+	global $wpdb;
+
+	// Multisite installations already have the signups table.
+	if ( ! empty( $wpdb->signups ) ) {
+		return;
+	}
+
+	$bp_signups = bp_core_get_table_prefix() . 'signups';
+
+	// Check for the table
+	$suppress = $wpdb->suppress_errors();
+	$table_exists = $wpdb->get_results( "DESCRIBE {$bp_signups};" );
+	$wpdb->suppress_errors( $suppress );
+
+	// Bail if the table exists
+	if ( ! empty( $table_exists ) ) {
+		return;
+	}
+
+	// Signups is not there and we need it so let's create it
+	require_once( buddypress()->plugin_dir . '/bp-core/admin/bp-core-schema.php' );
+
+	bp_core_install_signups();
+}
+
+/**
+ * Add "Mark as Spam/Ham" button to user row actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $actions User row action links.
+ * @param object $user_object Current user information.
+ * @return array $actions User row action links.
+ */
+function bp_core_admin_user_row_actions( $actions, $user_object ) {
+
+	if ( current_user_can( 'edit_user', $user_object->ID ) && bp_loggedin_user_id() != $user_object->ID ) {
+
+		$url = bp_get_admin_url( 'users.php' );
+
+		if ( bp_is_user_spammer( $user_object->ID ) ) {
+			$actions['ham'] = "<a href='" . wp_nonce_url( $url . "?action=ham&amp;user=$user_object->ID", 'bp-spam-user' ) . "'>" . __( 'Not Spam', 'buddypress' ) . "</a>";
+		} else {
+			$actions['spam'] = "<a class='submitdelete' href='" . wp_nonce_url( $url . "?action=spam&amp;user=$user_object->ID", 'bp-spam-user' ) . "'>" . __( 'Mark as Spam', 'buddypress' ) . "</a>";
+		}
+	}
+
+	return $actions;
+}
+
+/**
+ * Catch requests to mark individual users as spam/ham from users.php.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_core_admin_user_manage_spammers() {
+
+	// Print our inline scripts on non-Multisite
+	add_action( 'admin_footer', 'bp_core_admin_user_spammed_js' );
+
+	$action  = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false;
+	$updated = isset( $_REQUEST['updated'] ) ? $_REQUEST['updated'] : false;
+	$mode    = isset( $_POST['mode'] ) ? $_POST['mode'] : false;
+
+	// if this is a multisite, bulk request, stop now!
+	if ( 'list' == $mode ) {
+		return;
+	}
+
+	// Process a spam/ham request
+	if ( ! empty( $action ) && in_array( $action, array( 'spam', 'ham' ) ) ) {
+
+		check_admin_referer( 'bp-spam-user' );
+
+		$user_id = ! empty( $_REQUEST['user'] ) ? intval( $_REQUEST['user'] ) : false;
+
+		if ( empty( $user_id ) ) {
+			return;
+		}
+
+		$redirect = wp_get_referer();
+
+		$status = ( $action == 'spam' ) ? 'spam' : 'ham';
+
+		// Process the user
+		bp_core_process_spammer_status( $user_id, $status );
+
+		$redirect = add_query_arg( array( 'updated' => 'marked-' . $status ), $redirect);
+
+		wp_redirect( $redirect );
+	}
+
+	// Display feedback
+	if ( ! empty( $updated ) && in_array( $updated, array( 'marked-spam', 'marked-ham' ) ) ) {
+
+		if ( 'marked-spam' === $updated ) {
+			$notice = __( 'User marked as spammer. Spam users are visible only to site admins.', 'buddypress' );
+		} else {
+			$notice = __( 'User removed from spam.', 'buddypress' );
+		}
+
+		bp_core_add_admin_notice( $notice );
+	}
+}
+
+/**
+ * Inline script that adds the 'site-spammed' class to spammed users.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_core_admin_user_spammed_js() {
+	?>
+	<script type="text/javascript">
+		jQuery( document ).ready( function($) {
+			$( '.row-actions .ham' ).each( function() {
+				$( this ).closest( 'tr' ).addClass( 'site-spammed' );
+			});
+		});
+	</script>
+	<?php
+}
diff --git a/wp-content/plugins/buddypress/bp-core/admin/bp-core-schema.php b/wp-content/plugins/buddypress/bp-core/admin/bp-core-schema.php
index 64fd1f68e00c2c07dead517a7e6a6d07f8235333..3db4c1c5bbc15db6d4880c501dca8f28a1d041ca 100644
--- a/wp-content/plugins/buddypress/bp-core/admin/bp-core-schema.php
+++ b/wp-content/plugins/buddypress/bp-core/admin/bp-core-schema.php
@@ -1,4 +1,10 @@
 <?php
+/**
+ * BuddyPress DB schema
+ *
+ * @package BuddyPress
+ * @subpackage CoreAdministration
+ */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
@@ -17,12 +23,13 @@ function bp_core_install( $active_components = false ) {
 	if ( empty( $active_components ) )
 		$active_components = apply_filters( 'bp_active_components', bp_get_option( 'bp-active-components' ) );
 
-	// Core DB Tables
-	bp_core_install_notifications();
-
 	// Activity Streams
-	if ( !empty( $active_components['activity'] ) )
-		bp_core_install_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();
 
 	// Friend Connections
 	if ( !empty( $active_components['friends'] ) )
@@ -43,6 +50,10 @@ function bp_core_install( $active_components = false ) {
 	// Blog tracking
 	if ( !empty( $active_components['blogs'] ) )
 		bp_core_install_blog_tracking();
+
+	// Install the signups table
+	bp_core_install_signups();
+
 }
 
 function bp_core_install_notifications() {
@@ -336,3 +347,46 @@ function bp_core_install_blog_tracking() {
 
 	dbDelta( $sql );
 }
+
+/**
+ * Install the signups table.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @global $wpdb
+ * @uses wp_get_db_schema() to get WordPress ms_global schema
+ */
+function bp_core_install_signups() {
+	global $wpdb;
+
+	// Multisite installations already have the signups table
+	if ( ! empty( $wpdb->signups ) ) {
+		return;
+	}
+
+	$wpdb->signups = bp_core_get_table_prefix() . 'signups';
+
+	// Setting the charset to be sure WordPress upgrade.php is loaded
+	$charset_collate = bp_core_set_charset();
+
+	// Use WP's core CREATE TABLE query
+	$create_queries = wp_get_db_schema( 'ms_global' );
+
+	if ( ! is_array( $create_queries ) ) {
+		$create_queries = explode( ';', $create_queries );
+		$create_queries = array_filter( $create_queries );
+	}
+
+	// Filter out all the queries except wp_signups
+	foreach ( $create_queries as $key => $query ) {
+		if ( preg_match( "|CREATE TABLE ([^ ]*)|", $query, $matches ) ) {
+			if ( $wpdb->signups != trim( $matches[1], '`' ) ) {
+				unset( $create_queries[ $key ] );
+			}
+		}
+	}
+
+	if ( ! empty( $create_queries ) ) {
+		dbDelta( $create_queries );
+	}
+}
diff --git a/wp-content/plugins/buddypress/bp-core/admin/bp-core-settings.php b/wp-content/plugins/buddypress/bp-core/admin/bp-core-settings.php
index 01ed8c5d2498f2511cc9d5a831b71c90f7bd230c..e112df7083224bbd2bc9b0fee9bc38601e09a30e 100644
--- a/wp-content/plugins/buddypress/bp-core/admin/bp-core-settings.php
+++ b/wp-content/plugins/buddypress/bp-core/admin/bp-core-settings.php
@@ -103,6 +103,20 @@ function bp_admin_setting_callback_blogforum_comments() {
 <?php
 }
 
+/**
+ * Allow Heartbeat to refresh activity stream.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_admin_setting_callback_heartbeat() {
+?>
+
+	<input id="_bp_enable_heartbeat_refresh" name="_bp_enable_heartbeat_refresh" type="checkbox" value="1" <?php checked( bp_is_activity_heartbeat_active( true ) ); ?> />
+	<label for="_bp_enable_heartbeat_refresh"><?php _e( 'Automatically check for new items while viewing the activity stream', 'buddypress' ); ?></label>
+
+<?php
+}
+
 /**
  * Sanitization for _bp_force_buddyvar
  *
@@ -223,7 +237,7 @@ function bp_admin_setting_callback_bbpress_configuration() {
 
 	<?php if ( false === $file_exists ) : ?>
 
-		<a class="button" href="<?php bp_admin_url( 'admin.php?page=bb-forums-setup&repair=1' ); ?>" title="<?php _e( 'Attempt to save a new config file.', 'buddypress' ); ?>"><?php _e( 'Repair', 'buddypress' ) ?></a>
+		<a class="button" href="<?php bp_admin_url( 'admin.php?page=bb-forums-setup&repair=1' ); ?>" title="<?php esc_attr_e( 'Attempt to save a new config file.', 'buddypress' ); ?>"><?php _e( 'Repair', 'buddypress' ) ?></a>
 		<span class="attention"><?php _e( 'File does not exist', 'buddypress' ); ?></span>
 
 	<?php endif; ?>
@@ -264,7 +278,7 @@ function bp_core_admin_settings() {
 			<?php do_settings_sections( 'buddypress' ); ?>
 
 			<p class="submit">
-				<input type="submit" name="submit" class="button-primary" value="<?php _e( 'Save Settings', 'buddypress' ); ?>" />
+				<input type="submit" name="submit" class="button-primary" value="<?php esc_attr_e( 'Save Settings', 'buddypress' ); ?>" />
 			</p>
 		</form>
 	</div>
diff --git a/wp-content/plugins/buddypress/bp-core/admin/bp-core-slugs.php b/wp-content/plugins/buddypress/bp-core/admin/bp-core-slugs.php
index 8de0a08bf1e6fe330cc634beec1f3c514c3f8ae4..2c597c54d66c6189f79cd502a7b9809f0c37aa90 100644
--- a/wp-content/plugins/buddypress/bp-core/admin/bp-core-slugs.php
+++ b/wp-content/plugins/buddypress/bp-core/admin/bp-core-slugs.php
@@ -29,7 +29,7 @@ function bp_core_admin_slugs_settings() {
 			<?php bp_core_admin_slugs_options(); ?>
 
 			<p class="submit clear">
-				<input class="button-primary" type="submit" name="bp-admin-pages-submit" id="bp-admin-pages-submit" value="<?php _e( 'Save Settings', 'buddypress' ) ?>"/>
+				<input class="button-primary" type="submit" name="bp-admin-pages-submit" id="bp-admin-pages-submit" value="<?php esc_attr_e( 'Save Settings', 'buddypress' ) ?>"/>
 			</p>
 
 			<?php wp_nonce_field( 'bp-admin-pages-setup' ); ?>
@@ -102,7 +102,7 @@ function bp_core_admin_slugs_options() {
 							) ); ?>
 
 							<a href="<?php echo admin_url( add_query_arg( array( 'post_type' => 'page' ), 'post-new.php' ) ); ?>" class="button-secondary"><?php _e( 'New Page', 'buddypress' ); ?></a>
-							<input class="button-primary" type="submit" name="bp-admin-pages-single" value="<?php _e( 'Save', 'buddypress' ) ?>" />
+							<input class="button-primary" type="submit" name="bp-admin-pages-single" value="<?php esc_attr_e( 'Save', 'buddypress' ) ?>" />
 
 							<?php if ( !empty( $existing_pages[$name] ) ) : ?>
 
@@ -165,7 +165,7 @@ function bp_core_admin_slugs_options() {
 							) ) ?>
 
 							<a href="<?php echo admin_url( add_query_arg( array( 'post_type' => 'page' ), 'post-new.php' ) ); ?>" class="button-secondary"><?php _e( 'New Page', 'buddypress' ); ?></a>
-							<input class="button-primary" type="submit" name="bp-admin-pages-single" value="<?php _e( 'Save', 'buddypress' ) ?>" />
+							<input class="button-primary" type="submit" name="bp-admin-pages-single" value="<?php esc_attr_e( 'Save', 'buddypress' ) ?>" />
 
 							<?php if ( !empty( $existing_pages[$name] ) ) : ?>
 
diff --git a/wp-content/plugins/buddypress/bp-core/admin/bp-core-tools.php b/wp-content/plugins/buddypress/bp-core/admin/bp-core-tools.php
new file mode 100644
index 0000000000000000000000000000000000000000..5f2f32040f3a863f66c1d76fac8276ca1dd32061
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-core/admin/bp-core-tools.php
@@ -0,0 +1,349 @@
+<?php
+
+/**
+ * BuddyPress Tools panel
+ *
+ * @since BuddyPress (2.0.0)
+ */
+
+/**
+ * Render the BuddyPress Tools page.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_core_admin_tools() {
+	?>
+	<div class="wrap">
+		<?php screen_icon( 'buddypress'); ?>
+
+		<h2><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h2>
+
+		<p>
+			<?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?>
+			<?php esc_html_e( 'Use the tools below to manually recalculate these relationships.', 'buddypress' ); ?>
+		</p>
+		<p class="description"><?php esc_html_e( 'Some of these tools create substantial database overhead. Avoid running more than one repair job at a time.', 'buddypress' ); ?></p>
+
+		<form class="settings" method="post" action="">
+			<table class="form-table">
+				<tbody>
+					<tr valign="top">
+						<th scope="row"><?php esc_html_e( 'Data to Repair:', 'buddypress' ) ?></th>
+						<td>
+							<fieldset>
+								<legend class="screen-reader-text"><span><?php esc_html_e( 'Repair', 'buddypress' ) ?></span></legend>
+
+								<?php foreach ( bp_admin_repair_list() as $item ) : ?>
+
+									<label><input type="checkbox" class="checkbox" name="<?php echo esc_attr( $item[0] ) . '" id="' . esc_attr( str_replace( '_', '-', $item[0] ) ); ?>" value="1" /> <?php echo esc_html( $item[1] ); ?></label><br />
+
+								<?php endforeach; ?>
+
+							</fieldset>
+						</td>
+					</tr>
+				</tbody>
+			</table>
+
+			<fieldset class="submit">
+				<input class="button-primary" type="submit" name="bp-tools-submit" value="<?php esc_attr_e( 'Repair Items', 'buddypress' ); ?>" />
+				<?php wp_nonce_field( 'bp-do-counts' ); ?>
+			</fieldset>
+		</form>
+	</div>
+	<?php
+}
+
+/**
+ * Handle the processing and feedback of the admin tools page.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_admin_repair_handler() {
+	if ( ! bp_is_post_request() ) {
+		return;
+	}
+
+	if ( empty( $_POST['bp-tools-submit'] ) ) {
+		return;
+	}
+
+	check_admin_referer( 'bp-do-counts' );
+
+	// Stores messages
+	$messages = array();
+
+	wp_cache_flush();
+
+	foreach ( (array) bp_admin_repair_list() as $item ) {
+		if ( isset( $item[2] ) && isset( $_POST[$item[0]] ) && 1 === absint( $_POST[$item[0]] ) && is_callable( $item[2] ) ) {
+			$messages[] = call_user_func( $item[2] );
+		}
+	}
+
+	if ( count( $messages ) ) {
+		foreach ( $messages as $message ) {
+			bp_admin_tools_feedback( $message[1] );
+		}
+	}
+}
+add_action( bp_core_admin_hook(), 'bp_admin_repair_handler' );
+
+/**
+ * Get the array of the repair list.
+ *
+ * @return array
+ */
+function bp_admin_repair_list() {
+	$repair_list = array();
+
+	// Members:
+	// - member count
+	// - last_activity migration (2.0)
+	$repair_list[20] = array(
+		'bp-total-member-count',
+		__( 'Count total members', 'buddypress' ),
+		'bp_admin_repair_count_members',
+	);
+
+	$repair_list[25] = array(
+		'bp-last-activity',
+		__( 'Repair user "last activity" data', 'buddypress' ),
+		'bp_admin_repair_last_activity',
+	);
+
+	// Friends:
+	// - user friend count
+	if ( bp_is_active( 'friends' ) ) {
+		$repair_list[0] = array(
+			'bp-user-friends',
+			__( 'Count friends for each user', 'buddypress' ),
+			'bp_admin_repair_friend_count',
+		);
+	}
+
+	// Groups:
+	// - user group count
+	if ( bp_is_active( 'groups' ) ) {
+		$repair_list[10] = array(
+			'bp-group-count',
+			__( 'Count groups for each user', 'buddypress' ),
+			'bp_admin_repair_group_count',
+		);
+	}
+
+	ksort( $repair_list );
+
+	return (array) apply_filters( 'bp_repair_list', $repair_list );
+}
+
+/**
+ * Recalculate friend counts for each user.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return array
+ */
+function bp_admin_repair_friend_count() {
+	global $wpdb, $bp;
+
+	if ( ! bp_is_active( 'friends' ) ) {
+		return;
+	}
+
+	$statement = __( 'Counting the number of friends for each user&hellip; %s', 'buddypress' );
+	$result    = __( 'Failed!', 'buddypress' );
+
+	$sql_delete = "DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ( 'total_friend_count' );";
+	if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
+		return array( 1, sprintf( $statement, $result ) );
+	}
+
+	// Walk through all users on the site
+	$total_users = $wpdb->get_row( "SELECT count(ID) as c FROM {$wpdb->users}" )->c;
+
+	$updated = array();
+	if ( $total_users > 0 ) {
+		$per_query = 500;
+		$offset = 0;
+		while ( $offset < $total_users ) {
+			// Only bother updating counts for users who actually have friendships
+			$friendships = $wpdb->get_results( $wpdb->prepare( "SELECT initiator_user_id, friend_user_id FROM {$bp->friends->table_name} WHERE is_confirmed = 1 AND ( ( initiator_user_id > %d AND initiator_user_id <= %d ) OR ( friend_user_id > %d AND friend_user_id <= %d ) )", $offset, $offset + $per_query, $offset, $offset + $per_query ) );
+
+			// The previous query will turn up duplicates, so we
+			// filter them here
+			foreach ( $friendships as $friendship ) {
+				if ( ! isset( $updated[ $friendship->initiator_user_id ] ) ) {
+					BP_Friends_Friendship::total_friend_count( $friendship->initiator_user_id );
+					$updated[ $friendship->initiator_user_id ] = 1;
+				}
+
+				if ( ! isset( $updated[ $friendship->friend_user_id ] ) ) {
+					BP_Friends_Friendship::total_friend_count( $friendship->friend_user_id );
+					$updated[ $friendship->friend_user_id ] = 1;
+				}
+			}
+
+			$offset += $per_query;
+		}
+	} else {
+		return array( 2, sprintf( $statement, $result ) );
+	}
+
+	return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
+}
+
+/**
+ * Recalculate group counts for each user.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return array
+ */
+function bp_admin_repair_group_count() {
+	global $wpdb, $bp;
+
+	if ( ! bp_is_active( 'groups' ) ) {
+		return;
+	}
+
+	$statement = __( 'Counting the number of groups for each user&hellip; %s', 'buddypress' );
+	$result    = __( 'Failed!', 'buddypress' );
+
+	$sql_delete = "DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ( 'total_group_count' );";
+	if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
+		return array( 1, sprintf( $statement, $result ) );
+	}
+
+	// Walk through all users on the site
+	$total_users = $wpdb->get_row( "SELECT count(ID) as c FROM {$wpdb->users}" )->c;
+
+	if ( $total_users > 0 ) {
+		$per_query = 500;
+		$offset = 0;
+		while ( $offset < $total_users ) {
+			// But only bother to update counts for users that have groups
+			$users = $wpdb->get_col( $wpdb->prepare( "SELECT user_id FROM {$bp->groups->table_name_members} WHERE is_confirmed = 1 AND is_banned = 0 AND user_id > %d AND user_id <= %d", $offset, $offset + $per_query ) );
+
+			foreach ( $users as $user ) {
+				BP_Groups_Member::refresh_total_group_count_for_user( $user );
+			}
+
+			$offset += $per_query;
+		}
+	} else {
+		return array( 2, sprintf( $statement, $result ) );
+	}
+
+	return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
+}
+
+/**
+ * Recalculate the total number of active site members.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_admin_repair_count_members() {
+	$statement = __( 'Counting the number of active members on the site&hellip; %s', 'buddypress' );
+	delete_transient( 'bp_active_member_count' );
+	bp_core_get_active_member_count();
+	return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
+}
+
+/**
+ * Repair user last_activity data.
+ *
+ * Re-runs the migration from usermeta introduced in BP 2.0.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_admin_repair_last_activity() {
+	$statement = __( 'Determining last activity dates for each user&hellip; %s', 'buddypress' );
+	bp_last_activity_migrate();
+	return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
+}
+
+/**
+ * Assemble admin notices relating success/failure of repair processes.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $message Feedback message.
+ * @param unknown $class Unused.
+ */
+function bp_admin_tools_feedback( $message, $class = false ) {
+	if ( is_string( $message ) ) {
+		$message = '<p>' . $message . '</p>';
+		$class = $class ? $class : 'updated';
+	} elseif ( is_wp_error( $message ) ) {
+		$errors = $message->get_error_messages();
+
+		switch ( count( $errors ) ) {
+			case 0:
+				return false;
+				break;
+
+			case 1:
+				$message = '<p>' . $errors[0] . '</p>';
+				break;
+
+			default:
+				$message = '<ul>' . "\n\t" . '<li>' . implode( '</li>' . "\n\t" . '<li>', $errors ) . '</li>' . "\n" . '</ul>';
+				break;
+		}
+
+		$class = $class ? $class : 'error';
+	} else {
+		return false;
+	}
+
+	$message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
+	$message = str_replace( "'", "\'", $message );
+	$lambda  = create_function( '', "echo '$message';" );
+
+	add_action( bp_core_do_network_admin() ? 'network_admin_notices' : 'admin_notices', $lambda );
+
+	return $lambda;
+}
+
+/**
+ * Render the Available Tools page.
+ *
+ * We register this page on Network Admin as a top-level home for our
+ * BuddyPress tools. This displays the default content.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_core_admin_available_tools_page() {
+	?>
+	<div class="wrap">
+		<h2><?php esc_attr_e( 'Tools', 'buddypress' ) ?></h2>
+
+		<?php do_action( 'bp_network_tool_box' ); ?>
+
+	</div>
+	<?php
+}
+
+/**
+ * Render an introduction of BuddyPress tools on Available Tools page.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_core_admin_available_tools_intro() {
+	$query_arg = array(
+		'page' => 'bp-tools'
+	);
+
+	$page = bp_core_do_network_admin() ? 'admin.php' : 'tools.php' ;
+	$url  = add_query_arg( $query_arg, bp_get_admin_url( $page ) );
+	?>
+	<div class="tool-box">
+		<h3 class="title"><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h3>
+		<p>
+			<?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?>
+			<?php printf( esc_html_x( 'Use the %s to repair these relationships.', 'buddypress tools intro', 'buddypress' ), '<a href="' . esc_url( $url ) . '">' . esc_html__( 'BuddyPress Tools', 'buddypress' ) . '</a>' ); ?>
+		</p>
+	</div>
+	<?php
+}
diff --git a/wp-content/plugins/buddypress/bp-core/admin/css/common.css b/wp-content/plugins/buddypress/bp-core/admin/css/common.css
index dbf312f7ed933bfcb36132be4f732bf6fac973bf..e4766795acc709192dcd819e9e6afccf2c86fa8d 100644
--- a/wp-content/plugins/buddypress/bp-core/admin/css/common.css
+++ b/wp-content/plugins/buddypress/bp-core/admin/css/common.css
@@ -7,15 +7,18 @@
 /* Icon 32's
 ------------------------------------------------------------------------------*/
 
-div#icon-buddypress {
+body.branch-3-6 div#icon-buddypress,
+body.branch-3-7 div#icon-buddypress {
 	background: url('../images/icons32.png') no-repeat -370px -6px;
 }
 
-div#icon-buddypress-activity {
+body.branch-3-6 div#icon-buddypress-activity,
+body.branch-3-7 div#icon-buddypress-activity {
 	background: url('../images/icons32.png') no-repeat -10px -6px;
 }
 
-div#icon-buddypress-groups {
+body.branch-3-6 div#icon-buddypress-groups,
+body.branch-3-7 div#icon-buddypress-groups {
 	background: url('../images/icons32.png') no-repeat -250px -6px;
 }
 
@@ -23,48 +26,76 @@ div#icon-buddypress-groups {
 ------------------------------------------------------------------------------*/
 
 /* Backpat */
-ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image {
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image {
 	background-image: url('../images/menu.png') !important;
 	background-position: -178px -34px;
 }
 
-ul#adminmenu li.toplevel_page_bp-components:hover .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-general-settings:hover .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-components.wp-has-current-submenu .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-general-settings.wp-has-current-submenu .wp-menu-image {
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-components:hover .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-general-settings:hover .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-components.wp-has-current-submenu .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-general-settings.wp-has-current-submenu .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-components:hover .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-general-settings:hover .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-components.wp-has-current-submenu .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-general-settings.wp-has-current-submenu .wp-menu-image {
 	background-position: -178px -2px;
 }
 
 /* Activity */
-ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image {
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image {
 	background-image: url('../images/menu.png');
 	background-position: 0 -34px;
 }
-ul#adminmenu li.toplevel_page_bp-activity:hover .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-activity.current .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-activity.wp-has-current-submenu .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-activity_network:hover .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-activity_network.current .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-activity_network.wp-has-current-submenu .wp-menu-image {
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity:hover .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity.current .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity.wp-has-current-submenu .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network:hover .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network.current .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network.wp-has-current-submenu .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity:hover .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity.current .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity.wp-has-current-submenu .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network:hover .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network.current .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network.wp-has-current-submenu .wp-menu-image {
 	background-position: 0 -2px;
 }
 
 /* Groups */
-ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image {
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image {
 	background-image: url('../images/menu.png');
 	background-position: -61px -34px;
 }
-ul#adminmenu li.toplevel_page_bp-groups:hover .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-groups.current .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-groups.wp-has-current-submenu .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-groups_network:hover .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu-image,
-ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image {
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups:hover .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups.current .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups.wp-has-current-submenu .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network:hover .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu-image,
+body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups:hover .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups.current .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups.wp-has-current-submenu .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network:hover .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu-image,
+body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image {
 	background-position: -61px -2px;
 }
+
+/* Tools */
+#adminmenu .toplevel_page_network-tools div.wp-menu-image:before {
+    content: "";
+}
+
 th.column-gid {
 	width: 60px;
 }
@@ -90,73 +121,248 @@ table.bp-group-members .urole-column {
 /* Components
 ------------------------------------------------------------------------------*/
 
-.dashboard_page_bp-wizard td.plugin-title span,
+/* Dashicons */
+#adminmenu #toplevel_page_bp-activity .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-activity_user .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before {
+	content: "\f452";
+}
+
+#adminmenu #toplevel_page_bp-groups .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-groups_user .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before {
+	content: "\f456";
+}
+
+#adminmenu #toplevel_page_bp-notifications .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-notifications_user .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-notifications_network .wp-menu-image:before {
+	content: "\f439";
+}
+
+#adminmenu #toplevel_page_bp-messages .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-messages_user .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-messages_network .wp-menu-image:before {
+	content: "\f457";
+}
+
+#adminmenu #toplevel_page_bp-friends .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-friends_user .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-friends_network .wp-menu-image:before{
+	content: "\f454";
+}
+
+#adminmenu #toplevel_page_bp-settings .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-settings_user .wp-menu-image:before,
+#adminmenu #toplevel_page_bp-settings_network .wp-menu-image:before {
+	content: "\f108";
+}
+
+#adminmenu li.toplevel_page_bp-components .wp-menu-image,
+#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image {
+	content: "\f448";
+}
+
+/* Dashicons overrides for backward compatibility */
+body.branch-3-6 #adminmenu #toplevel_page_bp-activity .wp-menu-image:before,
+body.branch-3-6 #adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before,
+body.branch-3-6 #adminmenu #toplevel_page_bp-groups .wp-menu-image:before,
+body.branch-3-6 #adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before,
+body.branch-3-6 #adminmenu li.toplevel_page_bp-components .wp-menu-image,
+body.branch-3-6 #adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,
+body.branch-3-7 #adminmenu #toplevel_page_bp-activity .wp-menu-image:before,
+body.branch-3-7 #adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before,
+body.branch-3-7 #adminmenu #toplevel_page_bp-groups .wp-menu-image:before,
+body.branch-3-7 #adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before,
+body.branch-3-7 #adminmenu li.toplevel_page_bp-components .wp-menu-image,
+body.branch-3-7 #adminmenu li.toplevel_page_bp-general-settings .wp-menu-image {
+	content: "";
+}
+
+/* Settings - Dashicons (WP 3.8+) */
 .settings_page_bp-components td.plugin-title span {
 	float: left;
 	width: 18px;
 	height: 18px;
+	margin-right: 5px;
+}
+
+.settings_page_bp-components td.plugin-title span:before {
+	font-family: 'dashicons';
+	font-size: 18px;
+}
+
+.settings_page_bp-components tr.activity td.plugin-title span:before {
+	content: "\f452";
+}
+
+.settings_page_bp-components tr.notifications td.plugin-title span:before {
+	content: "\f339";
+}
+
+.settings_page_bp-components tr.xprofile td.plugin-title span:before {
+	content: "\f336";
+}
+
+.settings_page_bp-components tr.settings td.plugin-title span:before {
+	content: "\f108";
+}
+
+.settings_page_bp-components tr.groups td.plugin-title span:before {
+	content: "\f456";
+}
+
+.settings_page_bp-components tr.messages td.plugin-title span:before {
+	content: "\f457";
+}
+
+.settings_page_bp-components tr.forums td.plugin-title span:before {
+	content: "\f452";
+}
+
+.settings_page_bp-components tr.blogs td.plugin-title span:before {
+	content: "\f120";
+}
+
+.settings_page_bp-components tr.friends td.plugin-title span:before {
+	content: "\f454";
+}
+
+/* Settings - Legacy (< WP 3.8) */
+body.branch-3-6.settings_page_bp-components tr.activity td.plugin-title span:before,
+body.branch-3-6.settings_page_bp-components tr.notifications td.plugin-title span:before,
+body.branch-3-6.settings_page_bp-components tr.xprofile td.plugin-title span:before,
+body.branch-3-6.settings_page_bp-components tr.settings td.plugin-title span:before,
+body.branch-3-6.settings_page_bp-components tr.groups td.plugin-title span:before,
+body.branch-3-6.settings_page_bp-components tr.messages td.plugin-title span:before,
+body.branch-3-6.settings_page_bp-components tr.forums td.plugin-title span:before,
+body.branch-3-6.settings_page_bp-components tr.blogs td.plugin-title span:before,
+body.branch-3-6.settings_page_bp-components tr.friends td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.activity td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.notifications td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.xprofile td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.settings td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.groups td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.messages td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.forums td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.blogs td.plugin-title span:before,
+body.branch-3-7.settings_page_bp-components tr.friends td.plugin-title span:before {
+	content: "";
+}
+
+body.branch-3-6.settings_page_bp-components td.plugin-title span,
+body.branch-3-7.settings_page_bp-components td.plugin-title span {
 	background-image: url('../images/menu.png');
 	background-position: -4px -40px;
 	background-repeat: no-repeat;
-	margin-right: 5px;
 }
 
-.dashboard_page_bp-wizard tr.active td.plugin-title span,
-.settings_page_bp-components tr.active td.plugin-title span {
+body.branch-3-6.settings_page_bp-components tr.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.active td.plugin-title span {
 	background-position-y: -7px;
 }
 
-.dashboard_page_bp-wizard tr.activity td.plugin-title span,
-.settings_page_bp-components tr.activity td.plugin-title span {
-	background-position-x: -4px;
+body.branch-3-6.settings_page_bp-components tr.activity td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.activity td.plugin-title span {
+	background-position: -4px -40px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.activity.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.activity.active td.plugin-title span {
+	background-position: -4px -7px;
 }
 
-.dashboard_page_bp-wizard tr.xprofile td.plugin-title span,
-.settings_page_bp-components tr.xprofile td.plugin-title span {
+body.branch-3-6.settings_page_bp-components tr.xprofile td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.xprofile td.plugin-title span {
 	background-image: url('../images/menu-wp.png');
-	background-position-x: -305px;
+	background-position: -305px -40px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.xprofile.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.xprofile.active td.plugin-title span {
+	background-position: -305px -7px;
 }
 
-.dashboard_page_bp-wizard tr.settings td.plugin-title span,
-.settings_page_bp-components tr.settings td.plugin-title span {
+body.branch-3-6.settings_page_bp-components tr.settings td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.settings td.plugin-title span {
 	background-image: url('../images/menu-wp.png');
-	background-position-x: -334px;
+	background-position: -334px -40px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.settings.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.settings.active td.plugin-title span {
+	background-position: -334px -7px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.groups td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.groups td.plugin-title span {
+	background-position: -66px -40px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.groups.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.groups.active td.plugin-title span {
+	background-position: -66px -7px;
 }
 
-.dashboard_page_bp-wizard tr.groups td.plugin-title span,
-.settings_page_bp-components tr.groups td.plugin-title span {
-	background-position-x: -66px;
+body.branch-3-6.settings_page_bp-components tr.messages td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.messages td.plugin-title span {
+	background-position: -154px -40px;
 }
 
-.dashboard_page_bp-wizard tr.messages td.plugin-title span,
-.settings_page_bp-components tr.messages td.plugin-title span {
-	background-position-x: -154px;
+body.branch-3-6.settings_page_bp-components tr.messages.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.messages.active td.plugin-title span {
+	background-position: -154px -7px;
 }
 
-.dashboard_page_bp-wizard tr.forums td.plugin-title span,
-.settings_page_bp-components tr.forums td.plugin-title span {
+body.branch-3-6.settings_page_bp-components tr.forums td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.forums td.plugin-title span {
 	background-image: url('../images/menu-wp.png');
-	background-position-x: -36px;
+	background-position: -36px -40px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.forums.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.forums.active td.plugin-title span {
+	background-position: -36px -7px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.blogs td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.blogs td.plugin-title span {
+	background-position: -125px -40px;
 }
 
-.dashboard_page_bp-wizard tr.blogs td.plugin-title span,
-.settings_page_bp-components tr.blogs td.plugin-title span {
-	background-position-x: -125px;
+body.branch-3-6.settings_page_bp-components tr.blogs.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.blogs.active td.plugin-title span {
+	background-position: -125px -7px;
 }
 
-.dashboard_page_bp-wizard tr.friends td.plugin-title span,
-.settings_page_bp-components tr.friends td.plugin-title span {
-	background-position-x: -95px;
+body.branch-3-6.settings_page_bp-components tr.friends td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.friends td.plugin-title span {
+	background-position: -95px -40px;
 }
 
-.dashboard_page_bp-wizard tr.core td.plugin-title span,
-.settings_page_bp-components tr.core td.plugin-title span {
-	background-position-x: -184px;
+body.branch-3-6.settings_page_bp-components tr.friends.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.friends.active td.plugin-title span {
+	background-position: -95px -7px;
 }
 
-.dashboard_page_bp-wizard tr.members td.plugin-title span,
-.settings_page_bp-components tr.members td.plugin-title span {
-	background-position-x: -36px;
+body.branch-3-6.settings_page_bp-components tr.core td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.core td.plugin-title span {
+	background-position: -184px -40px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.core.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.core.active td.plugin-title span {
+	background-position: -184px -7px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.members td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.members td.plugin-title span {
+	background-position: -36px -40px;
+}
+
+body.branch-3-6.settings_page_bp-components tr.members.active td.plugin-title span,
+body.branch-3-7.settings_page_bp-components tr.members.active td.plugin-title span {
+	background-position: -36px -7px;
 }
 
 #bp-admin-component-form .widefat th {
@@ -167,15 +373,13 @@ table.bp-group-members .urole-column {
 /* Version Badge */
 
 .bp-badge {
-	padding-top: 142px;
-	height: 50px;
-	width: 173px;
-	color: #fafafa;
-	font-weight: bold;
-	font-size: 14px;
-	text-align: center;
-	margin: 0 -5px;
-	background: url('../images/badge.png') no-repeat;
+	font: normal 150px/1 'dashicons' !important;
+	color: #000;
+	display: inline-block;
+}
+
+.bp-badge:before {
+	content: "\f448";
 }
 
 .about-wrap .bp-badge {
@@ -194,20 +398,29 @@ table.bp-group-members .urole-column {
 @media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
 
 	/* Icon 32 */
-	div#icon-buddypress,
-	div#icon-buddypress-activity,
-	div#icon-buddypress-groups {
+	body.branch-3-6 div#icon-buddypress,
+	body.branch-3-6 div#icon-buddypress-activity,
+	body.branch-3-6 div#icon-buddypress-groups,
+	body.branch-3-7 div#icon-buddypress,
+	body.branch-3-7 div#icon-buddypress-activity,
+	body.branch-3-7 div#icon-buddypress-groups {
 		background-image: url('../images/icons64.png');
 		background-size: 419px 45px;
 	}
 
 	/* Backpat */
-	ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,
-	ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,
-	ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,
-	ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image,
-	ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,
-	ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image {
+	body.branch-3-6 ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,
+	body.branch-3-6 ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,
+	body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,
+	body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image,
+	body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,
+	body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image,
+	body.branch-3-7 ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,
+	body.branch-3-7 ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,
+	body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,
+	body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image,
+	body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,
+	body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image {
 		background-image: url('../images/menu-2x.png') !important;
 		background-size: 209px 64px;
 	}
diff --git a/wp-content/plugins/buddypress/bp-core/admin/css/common.min.css b/wp-content/plugins/buddypress/bp-core/admin/css/common.min.css
index c9a2542cda3baa1e78edbb00907a1d8d130b6eeb..9cfa2969b499dd92dbd0180909281dab283e2a18 100644
--- a/wp-content/plugins/buddypress/bp-core/admin/css/common.min.css
+++ b/wp-content/plugins/buddypress/bp-core/admin/css/common.min.css
@@ -1 +1 @@
-div#icon-buddypress{background:url('../images/icons32.png') no-repeat -370px -6px}div#icon-buddypress-activity{background:url('../images/icons32.png') no-repeat -10px -6px}div#icon-buddypress-groups{background:url('../images/icons32.png') no-repeat -250px -6px}ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image{background-image:url('../images/menu.png')!important;background-position:-178px -34px}ul#adminmenu li.toplevel_page_bp-components:hover .wp-menu-image,ul#adminmenu li.toplevel_page_bp-general-settings:hover .wp-menu-image,ul#adminmenu li.toplevel_page_bp-components.wp-has-current-submenu .wp-menu-image,ul#adminmenu li.toplevel_page_bp-general-settings.wp-has-current-submenu .wp-menu-image{background-position:-178px -2px}ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image{background-image:url('../images/menu.png');background-position:0 -34px}ul#adminmenu li.toplevel_page_bp-activity:hover .wp-menu-image,ul#adminmenu li.toplevel_page_bp-activity.current .wp-menu-image,ul#adminmenu li.toplevel_page_bp-activity.wp-has-current-submenu .wp-menu-image,ul#adminmenu li.toplevel_page_bp-activity_network:hover .wp-menu-image,ul#adminmenu li.toplevel_page_bp-activity_network.current .wp-menu-image,ul#adminmenu li.toplevel_page_bp-activity_network.wp-has-current-submenu .wp-menu-image{background-position:0 -2px}ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image{background-image:url('../images/menu.png');background-position:-61px -34px}ul#adminmenu li.toplevel_page_bp-groups:hover .wp-menu-image,ul#adminmenu li.toplevel_page_bp-groups.current .wp-menu-image,ul#adminmenu li.toplevel_page_bp-groups.wp-has-current-submenu .wp-menu-image,ul#adminmenu li.toplevel_page_bp-groups_network:hover .wp-menu-image,ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu-image,ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image{background-position:-61px -2px}th.column-gid{width:60px}td.column-gid{vertical-align:middle}table.bp-group-members th,table.bp-group-members td{padding:5px 0}table.bp-group-members .uid-column{padding-left:20px;padding-right:20px}table.bp-group-members .uname-column{width:70%}table.bp-group-members .urole-column{padding-left:20px;padding-right:20px}.dashboard_page_bp-wizard td.plugin-title span,.settings_page_bp-components td.plugin-title span{float:left;width:18px;height:18px;background-image:url('../images/menu.png');background-position:-4px -40px;background-repeat:no-repeat;margin-right:5px}.dashboard_page_bp-wizard tr.active td.plugin-title span,.settings_page_bp-components tr.active td.plugin-title span{background-position-y:-7px}.dashboard_page_bp-wizard tr.activity td.plugin-title span,.settings_page_bp-components tr.activity td.plugin-title span{background-position-x:-4px}.dashboard_page_bp-wizard tr.xprofile td.plugin-title span,.settings_page_bp-components tr.xprofile td.plugin-title span{background-image:url('../images/menu-wp.png');background-position-x:-305px}.dashboard_page_bp-wizard tr.settings td.plugin-title span,.settings_page_bp-components tr.settings td.plugin-title span{background-image:url('../images/menu-wp.png');background-position-x:-334px}.dashboard_page_bp-wizard tr.groups td.plugin-title span,.settings_page_bp-components tr.groups td.plugin-title span{background-position-x:-66px}.dashboard_page_bp-wizard tr.messages td.plugin-title span,.settings_page_bp-components tr.messages td.plugin-title span{background-position-x:-154px}.dashboard_page_bp-wizard tr.forums td.plugin-title span,.settings_page_bp-components tr.forums td.plugin-title span{background-image:url('../images/menu-wp.png');background-position-x:-36px}.dashboard_page_bp-wizard tr.blogs td.plugin-title span,.settings_page_bp-components tr.blogs td.plugin-title span{background-position-x:-125px}.dashboard_page_bp-wizard tr.friends td.plugin-title span,.settings_page_bp-components tr.friends td.plugin-title span{background-position-x:-95px}.dashboard_page_bp-wizard tr.core td.plugin-title span,.settings_page_bp-components tr.core td.plugin-title span{background-position-x:-184px}.dashboard_page_bp-wizard tr.members td.plugin-title span,.settings_page_bp-components tr.members td.plugin-title span{background-position-x:-36px}#bp-admin-component-form .widefat th{display:table-cell;vertical-align:top}.bp-badge{padding-top:142px;height:50px;width:173px;color:#fafafa;font-weight:bold;font-size:14px;text-align:center;margin:0 -5px;background:url('../images/badge.png') no-repeat}.about-wrap .bp-badge{position:absolute;top:0;right:0}body.rtl .about-wrap .bp-badge{right:auto;left:0}@media only screen and (-webkit-min-device-pixel-ratio:1.5){div#icon-buddypress,div#icon-buddypress-activity,div#icon-buddypress-groups{background-image:url('../images/icons64.png');background-size:419px 45px}ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image,ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image{background-image:url('../images/menu-2x.png')!important;background-size:209px 64px}.bp-badge{background-image:url('../images/badge-2x.png');background-size:173px 194px}}
\ No newline at end of file
+body.branch-3-6 div#icon-buddypress,body.branch-3-7 div#icon-buddypress{background:url('../images/icons32.png') no-repeat -370px -6px}body.branch-3-6 div#icon-buddypress-activity,body.branch-3-7 div#icon-buddypress-activity{background:url('../images/icons32.png') no-repeat -10px -6px}body.branch-3-6 div#icon-buddypress-groups,body.branch-3-7 div#icon-buddypress-groups{background:url('../images/icons32.png') no-repeat -250px -6px}body.branch-3-6 ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image{background-image:url('../images/menu.png') !important;background-position:-178px -34px}body.branch-3-6 ul#adminmenu li.toplevel_page_bp-components:hover .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-general-settings:hover .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-components.wp-has-current-submenu .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-general-settings.wp-has-current-submenu .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-components:hover .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-general-settings:hover .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-components.wp-has-current-submenu .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-general-settings.wp-has-current-submenu .wp-menu-image{background-position:-178px -2px}body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image{background-image:url('../images/menu.png');background-position:0 -34px}body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity:hover .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity.current .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity.wp-has-current-submenu .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network:hover .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network.current .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network.wp-has-current-submenu .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity:hover .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity.current .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity.wp-has-current-submenu .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network:hover .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network.current .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network.wp-has-current-submenu .wp-menu-image{background-position:0 -2px}body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image{background-image:url('../images/menu.png');background-position:-61px -34px}body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups:hover .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups.current .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups.wp-has-current-submenu .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network:hover .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups:hover .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups.current .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups.wp-has-current-submenu .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network:hover .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image{background-position:-61px -2px}#adminmenu .toplevel_page_network-tools div.wp-menu-image:before{content:""}th.column-gid{width:60px}td.column-gid{vertical-align:middle}table.bp-group-members th,table.bp-group-members td{padding:5px 0}table.bp-group-members .uid-column{padding-left:20px;padding-right:20px}table.bp-group-members .uname-column{width:70%}table.bp-group-members .urole-column{padding-left:20px;padding-right:20px}#adminmenu #toplevel_page_bp-activity .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_user .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before{content:"\f452"}#adminmenu #toplevel_page_bp-groups .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_user .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before{content:"\f456"}#adminmenu #toplevel_page_bp-notifications .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_user .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_network .wp-menu-image:before{content:"\f439"}#adminmenu #toplevel_page_bp-messages .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_user .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_network .wp-menu-image:before{content:"\f457"}#adminmenu #toplevel_page_bp-friends .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_user .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_network .wp-menu-image:before{content:"\f454"}#adminmenu #toplevel_page_bp-settings .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_user .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_network .wp-menu-image:before{content:"\f108"}#adminmenu li.toplevel_page_bp-components .wp-menu-image,#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image{content:"\f448"}body.branch-3-6 #adminmenu #toplevel_page_bp-activity .wp-menu-image:before,body.branch-3-6 #adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before,body.branch-3-6 #adminmenu #toplevel_page_bp-groups .wp-menu-image:before,body.branch-3-6 #adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before,body.branch-3-6 #adminmenu li.toplevel_page_bp-components .wp-menu-image,body.branch-3-6 #adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,body.branch-3-7 #adminmenu #toplevel_page_bp-activity .wp-menu-image:before,body.branch-3-7 #adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before,body.branch-3-7 #adminmenu #toplevel_page_bp-groups .wp-menu-image:before,body.branch-3-7 #adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before,body.branch-3-7 #adminmenu li.toplevel_page_bp-components .wp-menu-image,body.branch-3-7 #adminmenu li.toplevel_page_bp-general-settings .wp-menu-image{content:""}.settings_page_bp-components td.plugin-title span{float:left;width:18px;height:18px;margin-right:5px}.settings_page_bp-components td.plugin-title span:before{font-family:'dashicons';font-size:18px}.settings_page_bp-components tr.activity td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.notifications td.plugin-title span:before{content:"\f339"}.settings_page_bp-components tr.xprofile td.plugin-title span:before{content:"\f336"}.settings_page_bp-components tr.settings td.plugin-title span:before{content:"\f108"}.settings_page_bp-components tr.groups td.plugin-title span:before{content:"\f456"}.settings_page_bp-components tr.messages td.plugin-title span:before{content:"\f457"}.settings_page_bp-components tr.forums td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.blogs td.plugin-title span:before{content:"\f120"}.settings_page_bp-components tr.friends td.plugin-title span:before{content:"\f454"}body.branch-3-6.settings_page_bp-components tr.activity td.plugin-title span:before,body.branch-3-6.settings_page_bp-components tr.notifications td.plugin-title span:before,body.branch-3-6.settings_page_bp-components tr.xprofile td.plugin-title span:before,body.branch-3-6.settings_page_bp-components tr.settings td.plugin-title span:before,body.branch-3-6.settings_page_bp-components tr.groups td.plugin-title span:before,body.branch-3-6.settings_page_bp-components tr.messages td.plugin-title span:before,body.branch-3-6.settings_page_bp-components tr.forums td.plugin-title span:before,body.branch-3-6.settings_page_bp-components tr.blogs td.plugin-title span:before,body.branch-3-6.settings_page_bp-components tr.friends td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.activity td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.notifications td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.xprofile td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.settings td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.groups td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.messages td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.forums td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.blogs td.plugin-title span:before,body.branch-3-7.settings_page_bp-components tr.friends td.plugin-title span:before{content:""}body.branch-3-6.settings_page_bp-components td.plugin-title span,body.branch-3-7.settings_page_bp-components td.plugin-title span{background-image:url('../images/menu.png');background-position:-4px -40px;background-repeat:no-repeat}body.branch-3-6.settings_page_bp-components tr.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.active td.plugin-title span{background-position-y:-7px}body.branch-3-6.settings_page_bp-components tr.activity td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.activity td.plugin-title span{background-position:-4px -40px}body.branch-3-6.settings_page_bp-components tr.activity.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.activity.active td.plugin-title span{background-position:-4px -7px}body.branch-3-6.settings_page_bp-components tr.xprofile td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.xprofile td.plugin-title span{background-image:url('../images/menu-wp.png');background-position:-305px -40px}body.branch-3-6.settings_page_bp-components tr.xprofile.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.xprofile.active td.plugin-title span{background-position:-305px -7px}body.branch-3-6.settings_page_bp-components tr.settings td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.settings td.plugin-title span{background-image:url('../images/menu-wp.png');background-position:-334px -40px}body.branch-3-6.settings_page_bp-components tr.settings.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.settings.active td.plugin-title span{background-position:-334px -7px}body.branch-3-6.settings_page_bp-components tr.groups td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.groups td.plugin-title span{background-position:-66px -40px}body.branch-3-6.settings_page_bp-components tr.groups.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.groups.active td.plugin-title span{background-position:-66px -7px}body.branch-3-6.settings_page_bp-components tr.messages td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.messages td.plugin-title span{background-position:-154px -40px}body.branch-3-6.settings_page_bp-components tr.messages.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.messages.active td.plugin-title span{background-position:-154px -7px}body.branch-3-6.settings_page_bp-components tr.forums td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.forums td.plugin-title span{background-image:url('../images/menu-wp.png');background-position:-36px -40px}body.branch-3-6.settings_page_bp-components tr.forums.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.forums.active td.plugin-title span{background-position:-36px -7px}body.branch-3-6.settings_page_bp-components tr.blogs td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.blogs td.plugin-title span{background-position:-125px -40px}body.branch-3-6.settings_page_bp-components tr.blogs.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.blogs.active td.plugin-title span{background-position:-125px -7px}body.branch-3-6.settings_page_bp-components tr.friends td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.friends td.plugin-title span{background-position:-95px -40px}body.branch-3-6.settings_page_bp-components tr.friends.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.friends.active td.plugin-title span{background-position:-95px -7px}body.branch-3-6.settings_page_bp-components tr.core td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.core td.plugin-title span{background-position:-184px -40px}body.branch-3-6.settings_page_bp-components tr.core.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.core.active td.plugin-title span{background-position:-184px -7px}body.branch-3-6.settings_page_bp-components tr.members td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.members td.plugin-title span{background-position:-36px -40px}body.branch-3-6.settings_page_bp-components tr.members.active td.plugin-title span,body.branch-3-7.settings_page_bp-components tr.members.active td.plugin-title span{background-position:-36px -7px}#bp-admin-component-form .widefat th{display:table-cell;vertical-align:top}.bp-badge{font:normal 150px/1 'dashicons' !important;color:#000;display:inline-block}.bp-badge:before{content:"\f448"}.about-wrap .bp-badge{position:absolute;top:0;right:0}body.rtl .about-wrap .bp-badge{right:auto;left:0}@media only screen and (-webkit-min-device-pixel-ratio:1.5){body.branch-3-6 div#icon-buddypress,body.branch-3-6 div#icon-buddypress-activity,body.branch-3-6 div#icon-buddypress-groups,body.branch-3-7 div#icon-buddypress,body.branch-3-7 div#icon-buddypress-activity,body.branch-3-7 div#icon-buddypress-groups{background-image:url('../images/icons64.png');background-size:419px 45px}body.branch-3-6 ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,body.branch-3-6 ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-components .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-activity_network .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image,body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image{background-image:url('../images/menu-2x.png') !important;background-size:209px 64px}.bp-badge{background-image:url('../images/badge-2x.png');background-size:173px 194px}}
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-actions.php b/wp-content/plugins/buddypress/bp-core/bp-core-actions.php
index 57b378d1fc7095087d6e88e448e2dd231d168c2e..df61f5a5d18b62a31bae99508386981c59956a57 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-actions.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-actions.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Filters & Actions
+ * BuddyPress Filters & Actions.
  *
  * @package BuddyPress
  * @subpackage Hooks
@@ -16,7 +16,7 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Attach BuddyPress to WordPress
+ * Attach BuddyPress to WordPress.
  *
  * BuddyPress uses its own internal actions to help aid in third-party plugin
  * development, and to limit the amount of potential future code changes when
@@ -33,6 +33,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
   */
 add_action( 'plugins_loaded',          'bp_loaded',                 10    );
 add_action( 'init',                    'bp_init',                   10    );
+add_action( 'parse_query',             'bp_parse_query',            2     ); // Early for overrides
 add_action( 'wp',                      'bp_ready',                  10    );
 add_action( 'set_current_user',        'bp_setup_current_user',     10    );
 add_action( 'setup_theme',             'bp_setup_theme',            10    );
@@ -69,6 +70,8 @@ add_action( 'bp_init', 'bp_setup_nav',               6  );
 add_action( 'bp_init', 'bp_setup_title',             8  );
 add_action( 'bp_init', 'bp_core_load_admin_bar_css', 12 );
 add_action( 'bp_init', 'bp_add_rewrite_tags',        20 );
+add_action( 'bp_init', 'bp_add_rewrite_rules',       30 );
+add_action( 'bp_init', 'bp_add_permastructs',        40 );
 
 /**
  * bp_template_redirect - Attached to 'template_redirect' above
@@ -79,10 +82,13 @@ add_action( 'bp_init', 'bp_add_rewrite_tags',        20 );
  * Note that we currently use template_redirect versus template include because
  * BuddyPress is a bully and overrides the existing themes output in many
  * places. This won't always be this way, we promise.
- *                                                v---Load order
+ *                                                           v---Load order
  */
-add_action( 'bp_template_redirect', 'bp_actions', 4 );
-add_action( 'bp_template_redirect', 'bp_screens', 6 );
+add_action( 'bp_template_redirect', 'bp_redirect_canonical', 2  );
+add_action( 'bp_template_redirect', 'bp_actions',            4  );
+add_action( 'bp_template_redirect', 'bp_screens',            6  );
+add_action( 'bp_template_redirect', 'bp_post_request',       10 );
+add_action( 'bp_template_redirect', 'bp_get_request',        10 );
 
 /**
  * Add the BuddyPress functions file
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-admin.php b/wp-content/plugins/buddypress/bp-core/bp-core-admin.php
index 7fb67f5ed2424c628eb25044f94b73cb92de8a5f..8c36a66fc68d492c22fb2ee6e0ffdb4b7d84c08f 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-admin.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-admin.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * Main BuddyPress Admin Class
+ * Main BuddyPress Admin Class.
  *
  * @package BuddyPress
  * @subpackage CoreAdministration
@@ -12,53 +12,73 @@ if ( !defined( 'ABSPATH' ) ) exit;
 
 if ( !class_exists( 'BP_Admin' ) ) :
 /**
- * Loads BuddyPress plugin admin area
+ * Load BuddyPress plugin admin area.
  *
  * @package BuddyPress
  * @subpackage CoreAdministration
- * @since BuddyPress (1.6)
+ *
+ * @since BuddyPress (1.6.0)
  */
 class BP_Admin {
 
 	/** Directory *************************************************************/
 
 	/**
-	 * @var string Path to the BuddyPress admin directory
+	 * Path to the BuddyPress admin directory.
+	 *
+	 * @var string $admin_dir
 	 */
 	public $admin_dir = '';
 
 	/** URLs ******************************************************************/
 
 	/**
-	 * @var string URL to the BuddyPress admin directory
+	 * URL to the BuddyPress admin directory.
+	 *
+	 * @var string $admin_url
 	 */
 	public $admin_url = '';
 
 	/**
-	 * @var string URL to the BuddyPress images directory
+	 * URL to the BuddyPress images directory.
+	 *
+	 * @var string $images_url
 	 */
 	public $images_url = '';
 
 	/**
-	 * @var string URL to the BuddyPress admin CSS directory
+	 * URL to the BuddyPress admin CSS directory.
+	 *
+	 * @var string $css_url
 	 */
 	public $css_url = '';
 
 	/**
-	 * @var string URL to the BuddyPress admin JS directory
+	 * URL to the BuddyPress admin JS directory.
+	 *
+	 * @var string
 	 */
 	public $js_url = '';
 
+	/** Other *****************************************************************/
+
+	/**
+	 * Notices used for user feedback, like saving settings.
+	 *
+	 * @var array()
+	 */
+	public $notices = array();
+
 	/** Methods ***************************************************************/
 
 	/**
-	 * The main BuddyPress admin loader
+	 * The main BuddyPress admin loader.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @uses BP_Admin::setup_globals() Setup the globals needed
-	 * @uses BP_Admin::includes() Include the required files
-	 * @uses BP_Admin::setup_actions() Setup the hooks and actions
+	 * @uses BP_Admin::setup_globals() Setup the globals needed.
+	 * @uses BP_Admin::includes() Include the required files.
+	 * @uses BP_Admin::setup_actions() Setup the hooks and actions.
 	 */
 	public function __construct() {
 		$this->setup_globals();
@@ -67,10 +87,10 @@ class BP_Admin {
 	}
 
 	/**
-	 * Admin globals
+	 * Set admin-related globals.
 	 *
-	 * @since BuddyPress (1.6)
 	 * @access private
+	 * @since BuddyPress (1.6.0)
 	 */
 	private function setup_globals() {
 		$bp = buddypress();
@@ -84,12 +104,15 @@ class BP_Admin {
 
 		// Main settings page
 		$this->settings_page = bp_core_do_network_admin() ? 'settings.php' : 'options-general.php';
+
+		// Main capability
+		$this->capability = bp_core_do_network_admin() ? 'manage_network_options' : 'manage_options';
 	}
 
 	/**
-	 * Include required files
+	 * Include required files.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 * @access private
 	 */
 	private function includes() {
@@ -98,16 +121,17 @@ class BP_Admin {
 		require( $this->admin_dir . 'bp-core-functions.php'  );
 		require( $this->admin_dir . 'bp-core-components.php' );
 		require( $this->admin_dir . 'bp-core-slugs.php'      );
+		require( $this->admin_dir . 'bp-core-tools.php'      );
 	}
 
 	/**
-	 * Setup the admin hooks, actions and filters
+	 * Set up the admin hooks, actions, and filters.
 	 *
-	 * @since BuddyPress (1.6)
 	 * @access private
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @uses add_action() To add various actions
-	 * @uses add_filter() To add various filters
+	 * @uses add_action() To add various actions.
+	 * @uses add_filter() To add various filters.
 	 */
 	private function setup_actions() {
 
@@ -124,24 +148,41 @@ class BP_Admin {
 
 		/** BuddyPress Actions ************************************************/
 
+		// Load the BuddyPress metabox in the WP Nav Menu Admin UI
+		add_action( 'load-nav-menus.php', 'bp_admin_wp_nav_menu_meta_box' );
+
 		// Add settings
 		add_action( 'bp_register_admin_settings', array( $this, 'register_admin_settings' ) );
 
+		// Add a link to BuddyPress About page to the admin bar
+		add_action( 'admin_bar_menu', array( $this, 'admin_bar_about_link' ), 15 );
+
+		// Add a description of new BuddyPress tools in the available tools page
+		add_action( 'tool_box', 'bp_core_admin_available_tools_intro' );
+		add_action( 'bp_network_tool_box', 'bp_core_admin_available_tools_intro' );
+
+		// On non-multisite, catch
+		add_action( 'load-users.php', 'bp_core_admin_user_manage_spammers' );
+
 		/** Filters ***********************************************************/
 
 		// Add link to settings page
 		add_filter( 'plugin_action_links',               array( $this, 'modify_plugin_action_links' ), 10, 2 );
 		add_filter( 'network_admin_plugin_action_links', array( $this, 'modify_plugin_action_links' ), 10, 2 );
+
+		// Add "Mark as Spam" row actions on users.php
+		add_filter( 'ms_user_row_actions', 'bp_core_admin_user_row_actions', 10, 2 );
+		add_filter( 'user_row_actions',    'bp_core_admin_user_row_actions', 10, 2 );
 	}
 
 	/**
-	 * Add the navigational menu elements
+	 * Add the navigational menu elements.
 	 *
 	 * @since BuddyPress (1.6)
 	 *
-	 * @uses add_management_page() To add the Recount page in Tools section
+	 * @uses add_management_page() To add the Recount page in Tools section.
 	 * @uses add_options_page() To add the Forums settings page in Settings
-	 *                           section
+	 *       section.
 	 */
 	public function admin_menus() {
 
@@ -173,7 +214,7 @@ class BP_Admin {
 		$hooks[] = add_menu_page(
 			__( 'BuddyPress', 'buddypress' ),
 			__( 'BuddyPress', 'buddypress' ),
-			'manage_options',
+			$this->capability,
 			'bp-general-settings',
 			'bp_core_admin_backpat_menu',
 			'div'
@@ -183,7 +224,7 @@ class BP_Admin {
 			'bp-general-settings',
 			__( 'BuddyPress Help', 'buddypress' ),
 			__( 'Help', 'buddypress' ),
-			'manage_options',
+			$this->capability,
 			'bp-general-settings',
 			'bp_core_admin_backpat_page'
 		);
@@ -193,7 +234,7 @@ class BP_Admin {
 			$this->settings_page,
 			__( 'BuddyPress Components', 'buddypress' ),
 			__( 'BuddyPress', 'buddypress' ),
-			'manage_options',
+			$this->capability,
 			'bp-components',
 			'bp_core_admin_components_settings'
 		);
@@ -202,7 +243,7 @@ class BP_Admin {
 			$this->settings_page,
 			__( 'BuddyPress Pages', 'buddypress' ),
 			__( 'BuddyPress Pages', 'buddypress' ),
-			'manage_options',
+			$this->capability,
 			'bp-page-settings',
 			'bp_core_admin_slugs_settings'
 		);
@@ -211,11 +252,47 @@ class BP_Admin {
 			$this->settings_page,
 			__( 'BuddyPress Settings', 'buddypress' ),
 			__( 'BuddyPress Settings', 'buddypress' ),
-			'manage_options',
+			$this->capability,
 			'bp-settings',
 			'bp_core_admin_settings'
 		);
 
+		// For consistency with non-Multisite, we add a Tools menu in
+		// the Network Admin as a home for our Tools panel
+		if ( is_multisite() && bp_core_do_network_admin() ) {
+			$tools_parent = 'network-tools';
+
+			$hooks[] = add_menu_page(
+				__( 'Tools', 'buddypress' ),
+				__( 'Tools', 'buddypress' ),
+				$this->capability,
+				$tools_parent,
+				'bp_core_tools_top_level_item',
+				'',
+				24 // just above Settings
+			);
+
+			$hooks[] = add_submenu_page(
+				$tools_parent,
+				__( 'Available Tools', 'buddypress' ),
+				__( 'Available Tools', 'buddypress' ),
+				$this->capability,
+				'available-tools',
+				'bp_core_admin_available_tools_page'
+			);
+		} else {
+			$tools_parent = 'tools.php';
+		}
+
+		$hooks[] = add_submenu_page(
+			$tools_parent,
+			__( 'BuddyPress Tools', 'buddypress' ),
+			__( 'BuddyPress', 'buddypress' ),
+			$this->capability,
+			'bp-tools',
+			'bp_core_admin_tools'
+		);
+
 		// Fudge the highlighted subnav item when on a BuddyPress admin page
 		foreach( $hooks as $hook ) {
 			add_action( "admin_head-$hook", 'bp_core_modify_admin_menu_highlight' );
@@ -223,13 +300,13 @@ class BP_Admin {
 	}
 
 	/**
-	 * Register the settings
+	 * Register the settings.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @uses add_settings_section() To add our own settings section
-	 * @uses add_settings_field() To add various settings fields
-	 * @uses register_setting() To register various settings
+	 * @uses add_settings_section() To add our own settings section.
+	 * @uses add_settings_field() To add various settings fields.
+	 * @uses register_setting() To register various settings.
 	 */
 	public function register_admin_settings() {
 
@@ -259,9 +336,7 @@ class BP_Admin {
 			// Add the main section
 			add_settings_section( 'bp_xprofile',      __( 'Profile Settings', 'buddypress' ), 'bp_admin_setting_callback_xprofile_section', 'buddypress'                );
 
-			// Allow avatar uploads
-			add_settings_field( 'bp-disable-avatar-uploads', __( 'Avatar Uploads',   'buddypress' ), 'bp_admin_setting_callback_avatar_uploads',   'buddypress', 'bp_xprofile' );
-			register_setting  ( 'buddypress',         'bp-disable-avatar-uploads',   'intval'                                                                                  );
+			$avatar_setting = 'bp_xprofile';
 
 			// Profile sync setting
 			add_settings_field( 'bp-disable-profile-sync',   __( 'Profile Syncing',  'buddypress' ), 'bp_admin_setting_callback_profile_sync',     'buddypress', 'bp_xprofile' );
@@ -275,6 +350,9 @@ class BP_Admin {
 			// Add the main section
 			add_settings_section( 'bp_groups',        __( 'Groups Settings',  'buddypress' ), 'bp_admin_setting_callback_groups_section',   'buddypress'              );
 
+			if ( empty( $avatar_setting ) )
+				$avatar_setting = 'bp_groups';
+
 			// Allow subscriptions setting
 			add_settings_field( 'bp_restrict_group_creation', __( 'Group Creation',   'buddypress' ), 'bp_admin_setting_callback_group_creation',   'buddypress', 'bp_groups' );
 			register_setting  ( 'buddypress',         'bp_restrict_group_creation',   'intval'                                                                                );
@@ -303,22 +381,52 @@ class BP_Admin {
 			add_settings_field( 'bp-disable-blogforum-comments', __( 'Blog &amp; Forum Comments', 'buddypress' ), 'bp_admin_setting_callback_blogforum_comments', 'buddypress', 'bp_activity' );
 			register_setting( 'buddypress', 'bp-disable-blogforum-comments', 'bp_admin_sanitize_callback_blogforum_comments' );
 
+			// Activity Heartbeat refresh
+			add_settings_field( '_bp_enable_heartbeat_refresh', __( 'Activity auto-refresh', 'buddypress' ), 'bp_admin_setting_callback_heartbeat', 'buddypress', 'bp_activity' );
+			register_setting( 'buddypress', '_bp_enable_heartbeat_refresh', 'intval' );
+
 			// Allow activity akismet
 			if ( is_plugin_active( 'akismet/akismet.php' ) && defined( 'AKISMET_VERSION' ) ) {
 				add_settings_field( '_bp_enable_akismet', __( 'Akismet',          'buddypress' ), 'bp_admin_setting_callback_activity_akismet', 'buddypress', 'bp_activity' );
 				register_setting  ( 'buddypress',         '_bp_enable_akismet',   'intval'                                                                                  );
 			}
 		}
+
+		/** Avatar upload for users or groups ************************************/
+
+		if ( ! empty( $avatar_setting ) ) {
+		    // Allow avatar uploads
+		    add_settings_field( 'bp-disable-avatar-uploads', __( 'Avatar Uploads',   'buddypress' ), 'bp_admin_setting_callback_avatar_uploads',   'buddypress', $avatar_setting );
+		    register_setting  ( 'buddypress',         'bp-disable-avatar-uploads',   'intval'                                                                                    );
+		}
 	}
 
 	/**
-	 * Add Settings link to plugins area
+	 * Add a link to BuddyPress About page to the admin bar.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param WP_Admin_Bar $wp_admin_bar As passed to 'admin_bar_menu'.
+	 */
+	public function admin_bar_about_link( $wp_admin_bar ) {
+		if ( is_user_logged_in() ) {
+			$wp_admin_bar->add_menu( array(
+				'parent' => 'wp-logo',
+				'id'     => 'bp-about',
+				'title'  => esc_html__( 'About BuddyPress', 'buddypress' ),
+				'href'   => add_query_arg( array( 'page' => 'bp-about' ), bp_get_admin_url( 'index.php' ) ),
+			) );
+		}
+	}
+
+	/**
+	 * Add Settings link to plugins area.
+	 *
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @param array $links Links array in which we would prepend our link
-	 * @param string $file Current plugin basename
-	 * @return array Processed links
+	 * @param array $links Links array in which we would prepend our link.
+	 * @param string $file Current plugin basename.
+	 * @return array Processed links.
 	 */
 	public function modify_plugin_action_links( $links, $file ) {
 
@@ -334,9 +442,9 @@ class BP_Admin {
 	}
 
 	/**
-	 * Add some general styling to the admin area
+	 * Add some general styling to the admin area.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 */
 	public function admin_head() {
 
@@ -344,15 +452,18 @@ class BP_Admin {
 		remove_submenu_page( $this->settings_page, 'bp-page-settings' );
 		remove_submenu_page( $this->settings_page, 'bp-settings'      );
 
+		// Network Admin Tools
+		remove_submenu_page( 'network-tools', 'network-tools' );
+
 		// About and Credits pages
 		remove_submenu_page( 'index.php', 'bp-about'   );
 		remove_submenu_page( 'index.php', 'bp-credits' );
 	}
 
 	/**
-	 * Add some general styling to the admin area
+	 * Add some general styling to the admin area.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 */
 	public function enqueue_scripts() {
 
@@ -366,9 +477,9 @@ class BP_Admin {
 	/** About *****************************************************************/
 
 	/**
-	 * Output the about screen
+	 * Output the about screen.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function about_screen() {
 		global $wp_rewrite;
@@ -377,18 +488,21 @@ class BP_Admin {
 
 		$pretty_permalinks_enabled = ! empty( $wp_rewrite->permalink_structure );
 
+		$image_base = buddypress()->plugin_url . 'bp-core/images/bp20/';
+
 		list( $display_version ) = explode( '-', bp_get_version() ); ?>
 
 		<div class="wrap about-wrap">
 			<h1><?php printf( __( 'Welcome to BuddyPress %s', 'buddypress' ), $display_version ); ?></h1>
 			<div class="about-text">
 				<?php if ( $is_new_install ) : ?>
-					<?php printf( __( 'BuddyPress %s is our safest, fastest, most flexible version ever.', 'buddypress' ), $display_version ); ?>
+					<?php printf( __( 'It&#8217;s a great time to use BuddyPress! With a focus on speed, admin tools, and developer enhancements, %s is our leanest and most powerful version yet.', 'buddypress' ), $display_version ); ?>
 				<?php else : ?>
-					<?php printf( __( 'Thank you for updating! BuddyPress %s is our safest, fastest, most flexible version ever.', 'buddypress' ), $display_version ); ?>
+					<?php printf( __( 'Thanks for updating! With a focus on speed, admin tools, and developer enhancements, BuddyPress %s is our leanest and most powerful version yet.', 'buddypress' ), $display_version ); ?>
 				<?php endif; ?>
 			</div>
-			<div class="bp-badge"><?php printf( __( 'Version %s', 'buddypress' ), $display_version ); ?></div>
+
+			<div class="bp-badge"></div>
 
 			<h2 class="nav-tab-wrapper">
 				<a class="nav-tab nav-tab-active" href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-about' ), 'index.php' ) ) ); ?>">
@@ -403,7 +517,9 @@ class BP_Admin {
 
 				<div class="feature-section">
 					<h4><?php _e( 'Your Default Setup', 'buddypress' ); ?></h4>
-					<p><?php printf(
+
+					<?php if ( bp_is_active( 'members' ) && bp_is_active( 'activity' ) && current_user_can( $this->capability ) ) : ?>
+						<p><?php printf(
 						__( 'BuddyPress&#8217;s powerful features help your users connect and collaborate. To help get your community started, we&#8217;ve activated two of the most commonly used tools in BP: <strong>Extended Profiles</strong> and <strong>Activity Streams</strong>. See these components in action at the %1$s and %2$s directories, and be sure to spend a few minutes <a href="%3$s">configuring user profiles</a>. Want to explore more of BP&#8217;s features? Visit the <a href="%4$s">Components panel</a>.', 'buddypress' ),
 						$pretty_permalinks_enabled ? '<a href="' . trailingslashit( bp_get_root_domain() . '/' . bp_get_members_root_slug() ) . '">' . __( 'Members', 'buddypress' ) . '</a>' : __( 'Members', 'buddypress' ),
 						$pretty_permalinks_enabled ? '<a href="' . trailingslashit( bp_get_root_domain() . '/' . bp_get_activity_root_slug() ) . '">' . __( 'Activity', 'buddypress' ) . '</a>' : __( 'Activity', 'buddypress' ),
@@ -411,87 +527,132 @@ class BP_Admin {
 						bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), $this->settings_page ) )
 					); ?></p>
 
+					<?php else : ?>
+						<p><?php printf(
+						__( 'BuddyPress&#8217;s powerful features help your users connect and collaborate. Want to explore BP&#8217;s features? Visit the <a href="%s">Components panel</a>.', 'buddypress' ),
+						bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), $this->settings_page ) )
+					); ?></p>
+
+					<?php endif; ?>
+
 					<h4><?php _e( 'Community and Support', 'buddypress' ); ?></h4>
 					<p><?php _e( 'Looking for help? The <a href="http://codex.buddypress.org/">BuddyPress Codex</a> has you covered, with dozens of user-contributed guides on how to configure and use your BP site. Can&#8217;t find what you need? Stop by <a href="http://buddypress.org/support/">our support forums</a>, where a vibrant community of BuddyPress users and developers is waiting to share tips, show off their sites, talk about the future of BuddyPress, and much more.', 'buddypress' ) ?></p>
 				</div>
+				<hr />
 
 			<?php endif; ?>
 
 			<div class="changelog">
-				<h3><?php _e( 'Improved Theme Integration', 'buddypress' ); ?></h3>
-
-				<div class="feature-section">
-					<h4><?php _e( 'Hey, Good Lookin&#8217;', 'buddypress' ); ?></h4>
-					<p><?php _e( 'We&#8217;ve streamlined our stylesheets, so that BuddyPress content looks more at home in your theme. And theme developers will love BP&#8217;s new hierarchies that make it easy to override specific top-level templates, stylesheets, and JavaScript files.', 'buddypress' ) ?></p>
-				</div>
+				<h2 class="about-headline-callout"><?php _e( 'Performance Improvements', 'buddypress' ); ?></h2>
+				<img class="about-overview-img" src="<?php echo $image_base ?>performance.png" alt="Performance improvements in BP 2.0" />
+				<p><?php esc_html_e( 'Whether your community has tens of members or tens of thousands, we think the performance improvements in BuddyPress 2.0 will knock your socks off. We&#8217;ve slashed our memory footprint and query overhead across the board, with a special focus on the Activity and Members components.', 'buddypress' ) ?></p>
 			</div>
 
-			<div class="changelog">
-				<h3><?php _e( 'Better Group Member Management', 'buddypress' ); ?></h3>
-
-				<div class="feature-section">
-					<h4><?php _e( '<em>Add</em>, <em>Remove</em>, and More, in a Snap', 'buddypress' ); ?></h4>
-
-					<?php
-					$group_admin_text = __( 'Groups administration panel', 'buddypress' );
-					if ( bp_is_active( 'groups' ) ) {
-						$group_admin_text = '<a href="' . bp_get_admin_url( add_query_arg( array( 'page' => 'bp-groups' ), 'admin.php' ) ) . '">' . $group_admin_text . '</a>';
-					}
-					?>
-
-					<p><?php printf(
-						__( 'The Manage Members section of the %s has been rewritten, to make it easier to handle groups with many members. We&#8217;ve also made the interface nicer to use, to ensure that you don&#8217;t make changes and then forget to save them.', 'buddypress' ),
-						$group_admin_text
-					); ?></p>
-				</div>
-			</div>
+			<hr />
 
 			<div class="changelog">
-				<h3><?php _e( 'Under the Hood', 'buddypress' ); ?></h3>
+				<h2 class="about-headline-callout"><?php _e( 'New Administrative Tools', 'buddypress' ); ?></h2>
 
-				<div class="feature-section three-col">
+				<div class="feature-section col two-col">
 					<div>
-						<h4><?php _e( 'Superpowered Group Extensions', 'buddypress' ); ?></h4>
-						<p><?php _e( '<code>BP_Group_Extension</code> has been overhauled, making it easier than ever before to add custom functionality to groups.', 'buddypress' ); ?></p>
+						<h4><?php esc_html_e( 'Extended Profiles in Admin', 'buddypress' ); ?></h4>
+						<p><?php esc_html_e( 'Site administrators can edit members&#8217; xProfile data at Dashboard > Users > Extended Profiles.', 'buddypress' ); ?></p>
+						<img src="<?php echo $image_base ?>admin-xprofile.jpg" style="width:90%" />
+					</div>
 
-						<h4><?php _e( 'Filter Groups or Activity by Metadata', 'buddypress' ); ?></h4>
-						<p><?php _e( '<code>bp_has_groups()</code> and <code>bp_has_activities()</code> now accept a <code>meta_query</code> paramater, for more powerful directory queries.', 'buddypress' ); ?></p>
+					<div class="last-feature">
+						<h4><?php esc_html_e( 'Registration Management', 'buddypress' ); ?></h4>
+						<p><?php esc_html_e( 'Perform common tasks with pending signups - including resending activation emails and manually activating accounts - on the new Pending tab of Dashboard > Users.', 'buddypress' ); ?></p>
+						<img src="<?php echo $image_base ?>users-pending.jpg" style="width:90%" />
 					</div>
+				</div>
 
+				<div class="feature-section col two-col">
 					<div>
-						<h4><?php _e( 'Feed Me, Seymour', 'buddypress' ); ?></h4>
-						<p><?php _e( 'The new <code>BP_Activity_Feed</code> class centralizes BP&#8217;s RSS logic, making our feeds more standards-compliant, and giving developers more tools for building custom feeds.', 'buddypress' ); ?></p>
+						<h4><?php esc_html_e( 'BuddyPress Repair Tools', 'buddypress' ); ?></h4>
+						<p><?php esc_html_e( 'Dashboard > Tools > BuddyPress contains a number of tools for correcting data that occasionally gets out of sync on BP installs.', 'buddypress' ); ?></p>
+						<img src="<?php echo $image_base ?>tools-buddypress.jpg" style="width:90%" />
+					</div>
 
-						<h4><?php _e( 'Disable @-Mentions', 'buddypress' ); ?></h4>
-						<p><?php _e( "Not using @-mentions? Disable them with <code>add_filter( 'bp_activity_do_mentions', '__return_false' );</code>", 'buddypress' ); ?></p>
+					<div class="feature-section col two-col">
+						<h4><?php esc_html_e( 'Mark Spammers in Admin', 'buddypress' ); ?></h4>
+						<p><?php esc_html_e( 'Admins on non-Multisite installations can now perform spam actions from Dashboard > Users > All Users.', 'buddypress' ); ?></p>
+						<img src="<?php echo $image_base ?>user-mark-spam.jpg" style="width:90%" />
 					</div>
+				</div>
+
 			</div>
 
-			<div class="return-to-dashboard">
-				<a href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), $this->settings_page ) ) ); ?>"><?php _e( 'Go to the BuddyPress Settings page', 'buddypress' ); ?></a>
+			<hr />
+
+			<div class="changelog">
+				<h2 class="about-headline-callout"><?php esc_html_e( 'A More Dynamic Activity Stream', 'buddypress' ); ?></h2>
+				<div class="feature-section col two-col">
+					<div>
+						<p><?php esc_html_e( 'Spend a lot of time viewing the activity stream? BuddyPress 2.0 automatically lets you know when new items are waiting to be loaded.', 'buddypress' ); ?></p>
+
+						<p><?php esc_html_e( 'The activity stream is better integrated with blog posts, too. Comment on a blog post, and an activity item is posted. Comment on a blog-related activity item, and a blog comment is posted. No more worrying about fractured conversations.', 'buddypress' ) ?></p>
+
+						<p><?php esc_html_e( 'We&#8217;ve also reworked the way that phrases like "Boone posted an update" are handled, so that they&#8217;re always up-to-date and always translatable.', 'buddypress' ) ?></p>
+					</div>
+
+					<div class="feature-section col two-col">
+						<img src="<?php echo $image_base ?>load-newest.jpg" style="width:90%" />
+					</div>
+				</div>
 			</div>
 
-		</div>
+			<hr />
+
+			<div class="changelog">
+				<h2 class="about-headline-callout"><?php esc_html_e( 'Developer Tools', 'buddypress' ); ?></h2>
+
+				<p><?php esc_html_e( 'BuddyPress 2.0 is full of new and improved tools for the theme and plugin developer. A few highlights:', 'buddypress' ) ?></p>
+					<ul>
+						<li><?php _e( 'The <code>BP_XProfile_Field_Type</code> class makes it a breeze to create new xProfile field types with custom display callbacks, validation, and more.', 'buddypress' ); ?></li>
+						 <li><?php _e( 'Major improvements have taken place with respect to object caching throughout BuddyPress. If you use Memcached, APC, or some other persistent object caching backend on your BuddyPress site, you should notice huge performance boosts.', 'buddypress' ); ?></li>
+						 <li><?php _e( 'Our internal metadata libraries have been rewritten to use WP&#8217;s <code>add_metadata()</code>, <code>update_metadata()</code>, and so on. This means greater consistency and parity between the components when storing and retrieving BuddyPress metadata.', 'buddypress' ); ?></li>
+						 <li><?php printf( __( '<a href="%s">&hellip;and lots more!</a>', 'buddypress' ), 'http://codex.buddypress.org/releases/version-2-0' ); ?></li>
+					</ul>
+				</div>
+
+				<hr />
+
+				<?php if ( current_user_can( $this->capability ) ) :?>
+					<div class="return-to-dashboard">
+						<a href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), $this->settings_page ) ) ); ?>"><?php _e( 'Go to the BuddyPress Settings page', 'buddypress' ); ?></a>
+					</div>
+				<?php endif ;?>
+
+			</div>
 
 		<?php
 	}
 
 	/**
-	 * Output the credits screen
+	 * Output the credits screen.
 	 *
-	 * Hardcoding this in here is pretty janky. It's fine for 2.2, but we'll
+	 * Hardcoding this in here is pretty janky. It's fine for now, but we'll
 	 * want to leverage api.wordpress.org eventually.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function credits_screen() {
 
+		$is_new_install = ! empty( $_GET['is_new_install'] );
+
 		list( $display_version ) = explode( '-', bp_get_version() ); ?>
 
 		<div class="wrap about-wrap">
 			<h1><?php printf( __( 'Welcome to BuddyPress %s', 'buddypress' ), $display_version ); ?></h1>
-			<div class="about-text"><?php printf( __( 'Thank you for updating to the latest version! BuddyPress %s is ready to make your community a safer, faster, and better looking place to hang out!', 'buddypress' ), $display_version ); ?></div>
-			<div class="bp-badge"><?php printf( __( 'Version %s', 'buddypress' ), $display_version ); ?></div>
+			<div class="about-text">
+				<?php if ( $is_new_install ) : ?>
+					<?php printf( __( 'It&#8217;s a great time to use BuddyPress! With a focus on speed, admin tools, and developer enhancements, %s is our leanest and most powerful version yet.', 'buddypress' ), $display_version ); ?>
+				<?php else : ?>
+					<?php printf( __( 'Thanks for updating! With a focus on speed, admin tools, and developer enhancements, BuddyPress %s is our leanest and most powerful version yet.', 'buddypress' ), $display_version ); ?>
+				<?php endif; ?>
+			</div>
+			<div class="bp-badge"></div>
 
 			<h2 class="nav-tab-wrapper">
 				<a href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-about' ), 'index.php' ) ) ); ?>" class="nav-tab">
@@ -505,11 +666,6 @@ class BP_Admin {
 
 			<h4 class="wp-people-group"><?php _e( 'Project Leaders', 'buddypress' ); ?></h4>
 			<ul class="wp-people-group " id="wp-people-group-project-leaders">
-				<li class="wp-person" id="wp-person-apeatling">
-					<a href="http://profiles.wordpress.org/apeatling"><img src="http://0.gravatar.com/avatar/bb29d699b5cba218c313b61aa82249da?s=60" class="gravatar" alt="Andy Peatling" /></a>
-					<a class="web" href="http://profiles.wordpress.org/apeatling">Andy Peatling</a>
-					<span class="title"><?php _e( 'Founding Developer', 'buddypress' ); ?></span>
-				</li>
 				<li class="wp-person" id="wp-person-johnjamesjacoby">
 					<a href="http://profiles.wordpress.org/johnjamesjacoby"><img src="http://0.gravatar.com/avatar/81ec16063d89b162d55efe72165c105f?s=60" class="gravatar" alt="John James Jacoby" /></a>
 					<a class="web" href="http://profiles.wordpress.org/johnjamesjacoby">John James Jacoby</a>
@@ -527,79 +683,88 @@ class BP_Admin {
 				</li>
 			</ul>
 
-			<h4 class="wp-people-group"><?php _e( 'Core Developers', 'buddypress' ); ?></h4>
-			<ul class="wp-people-group " id="wp-people-group-core-developers">
+			<h4 class="wp-people-group"><?php _e( 'Core Team', 'buddypress' ); ?></h4>
+			<ul class="wp-people-group " id="wp-people-group-core-team">
 				<li class="wp-person" id="wp-person-r-a-y">
 					<a href="http://profiles.wordpress.org/r-a-y"><img src="http://0.gravatar.com/avatar/3bfa556a62b5bfac1012b6ba5f42ebfa?s=60" class="gravatar" alt="Ray" /></a>
 					<a class="web" href="http://profiles.wordpress.org/r-a-y">Ray</a>
+					<span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span>
+				</li>
+				<li class="wp-person" id="wp-person-imath">
+					<a href="http://profiles.wordpress.org/imath"><img src="http://0.gravatar.com/avatar/8b208ca408dad63888253ee1800d6a03?s=60" class="gravatar" alt="Mathieu Viet" /></a>
+					<a class="web" href="http://profiles.wordpress.org/imath">Mathieu Viet</a>
+					<span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span>
+				</li>
+				<li class="wp-person" id="wp-person-mercime">
+					<a href="http://profiles.wordpress.org/mercime"><img src="http://0.gravatar.com/avatar/fae451be6708241627983570a1a1817a?s=60" class="gravatar" alt="Mercime" /></a>
+					<a class="web" href="http://profiles.wordpress.org/mercime">Mercime</a>
+					<span class="title"><?php _e( 'Navigator', 'buddypress' ); ?></span>
 				</li>
 			</ul>
 
 			<h4 class="wp-people-group"><?php _e( 'Recent Rockstars', 'buddypress' ); ?></h4>
 			<ul class="wp-people-group " id="wp-people-group-rockstars">
-				<li class="wp-person" id="wp-person-karmatosed">
-					<a href="http://profiles.wordpress.org/karmatosed"><img src="http://0.gravatar.com/avatar/d36d2c1821af9249b69ff7f5ed60529b?s=60" class="gravatar" alt="Tammie Lister" /></a>
-					<a class="web" href="http://profiles.wordpress.org/karmatosed">Tammie Lister</a>
-					<span class="title"><?php _e( 'Design Officer', 'buddypress' ); ?></span>
+				<li class="wp-person" id="wp-person-dcavins">
+					<a href="http://profiles.wordpress.org/dcavins"><img src="http://0.gravatar.com/avatar/a5fa7e83d59cb45ebb616235a176595a?s=60" class="gravatar" alt="David Cavins" /></a>
+					<a class="web" href="http://profiles.wordpress.org/dcavins">David Cavins</a>
 				</li>
-				<li class="wp-person" id="wp-person-mercime">
-					<a href="http://profiles.wordpress.org/mercime"><img src="http://0.gravatar.com/avatar/fae451be6708241627983570a1a1817a?s=60" class="gravatar" alt="Mercime" /></a>
-					<a class="web" href="http://profiles.wordpress.org/mercime">Mercime</a>
-					<span class="title"><?php _e( 'Support Officer', 'buddypress' ); ?></span>
+				<li class="wp-person" id="wp-person-henry-wright">
+					<a href="http://profiles.wordpress.org/henry.wright"><img src="http://0.gravatar.com/avatar/0da2f1a9340d6af196b870f6c107a248?s=60" class="gravatar" alt="Henry Wright" /></a>
+					<a class="web" href="http://profiles.wordpress.org/henry.wright">Henry Wright</a>
 				</li>
 			</ul>
 
-			<h4 class="wp-people-group"><?php _e( 'Core Contributors to BuddyPress 1.8', 'buddypress' ); ?></h4>
+			<h4 class="wp-people-group"><?php _e( 'Contributors to BuddyPress 2.0', 'buddypress' ); ?></h4>
 			<p class="wp-credits-list">
-				<a href="http://profiles.wordpress.org/boonebgorges">boonebgorges</a>,
-				<a href="http://profiles.wordpress.org/borkweb">borkweb</a>,
-				<a href="http://profiles.wordpress.org/chouf1">chouf1</a>,
-				<a href="http://profiles.wordpress.org/chriskeeble">chriskeeble</a>,
-				<a href="http://profiles.wordpress.org/chroniko">chroniko</a>,
-				<a href="http://profiles.wordpress.org/czarate">czarate</a>,
-				<a href="http://profiles.wordpress.org/danbp">danbp</a>,
-				<a href="http://profiles.wordpress.org/dcavins">dcavins</a>,
-				<a href="http://profiles.wordpress.org/dcowgill">dcowgill</a>,
-				<a href="http://profiles.wordpress.org/ddean">ddean</a>,
-				<a href="http://profiles.wordpress.org/djpaul">djpaul</a>,
-				<a href="http://profiles.wordpress.org/dontdream">dontdream</a>,
-				<a href="http://profiles.wordpress.org/eggproject">eggproject</a>,
-				<a href="http://profiles.wordpress.org/ericlewis">ericlewis</a>,
-				grahamwashbroo,
-				<a href="http://profiles.wordpress.org/hnla">hnla</a>,
-				<a href="http://profiles.wordpress.org/imath">imath</a>,
-				<a href="http://profiles.wordpress.org/johnjamesjacoby">johnjamesjacoby</a>,
-				<a href="http://profiles.wordpress.org/karmatosed">karmatosed</a>,
-				<a href="http://profiles.wordpress.org/lenasterg">lenasterg</a>,
-				<a href="http://profiles.wordpress.org/magnus78">magnus78</a>,
-				<a href="http://profiles.wordpress.org/megainfo">megainfo</a>,
-				<a href="http://profiles.wordpress.org/rogercoathup">rogercoathup</a>,
-				<a href="http://profiles.wordpress.org/mercime">mercime</a>,
-				<a href="http://profiles.wordpress.org/merty">merty</a>,
-				<a href="http://profiles.wordpress.org/mjustice">mjustice</a>,
-				<a href="http://profiles.wordpress.org/modemlooper">modemlooper</a>,
-				<a href="http://profiles.wordpress.org/mort3n">mort3n</a>,
-				<a href="http://profiles.wordpress.org/mukkundthanki">mukkundthanki</a>,
-				<a href="http://profiles.wordpress.org/nacin">nacin</a>,
-				<a href="http://profiles.wordpress.org/needle">needle</a>,
-				<a href="http://profiles.wordpress.org/r-a-y">r-a-y</a>,
-				<a href="http://profiles.wordpress.org/saurabhshukla">saurabhshukla</a>,
-				<a href="http://profiles.wordpress.org/sbrajesh">sbrajesh</a>,
-				<a href="http://profiles.wordpress.org/SergeyBiryukov">SergeyBiryukov</a>,
-				<a href="http://profiles.wordpress.org/SGr33n">SGr33n</a>,
-				<a href="http://profiles.wordpress.org/shanebp">shanebp</a>,
-				<a href="http://profiles.wordpress.org/splatte">splatte</a>,
-				<a href="http://profiles.wordpress.org/thebrandonallen">thebrandonallen</a>,
-				<a href="http://profiles.wordpress.org/themightymo">themightymo</a>,
-				<a href="http://profiles.wordpress.org/tivnet">tivnet</a>,
-				<a href="http://profiles.wordpress.org/trishasalas">trishasalas</a>,
-				<a href="http://profiles.wordpress.org/vegasgeek">vegasgeek</a>,
-				<a href="http://profiles.wordpress.org/wpdennis">wpdennis</a>
+				<a href="https://profiles.wordpress.org/boonebgorges/">boonebgorges</a>,
+				<a href="https://profiles.wordpress.org/Bowromir/">Bowromir</a>,
+				<a href="https://profiles.wordpress.org/burakali/">burakali</a>,
+				<a href="https://profiles.wordpress.org/chouf1/">chouf1</a>,
+				<a href="https://profiles.wordpress.org/cmmarslender/">cmmarslender</a>,
+				<a href="https://profiles.wordpress.org/danbp/">danbp</a>,
+				<a href="https://profiles.wordpress.org/dcavins/">dcavins</a>,
+				<a href="https://profiles.wordpress.org/Denis-de-Bernardy/">Denis-de-Bernardy</a>,
+				<a href="https://profiles.wordpress.org/DJPaul/">DJPaul</a>,
+				<a href="https://profiles.wordpress.org/ericlewis/">ericlewis</a>,
+				<a href="https://profiles.wordpress.org/glyndavidson/">glyndavidson</a>,
+				<a href="https://profiles.wordpress.org/graham-washbrook/">graham-washbrook</a>,
+				<a href="https://profiles.wordpress.org/henrywright/">henrywright</a>,
+				<a href="https://profiles.wordpress.org/henry.wright/">henry.wright</a>,
+				<a href="https://profiles.wordpress.org/hnla/">hnla</a>,
+				<a href="https://profiles.wordpress.org/imath/">imath</a>,
+				<a href="https://profiles.wordpress.org/johnjamesjacoby/">johnjamesjacoby</a>,
+				<a href="https://profiles.wordpress.org/karmatosed/">karmatosed</a>,
+				<a href="https://profiles.wordpress.org/lenasterg/">lenasterg</a>,
+				<a href="https://profiles.wordpress.org/MacPresss/">MacPresss</a>,
+				<a href="https://profiles.wordpress.org/markoheijnen/">markoheijnen</a>,
+				<a href="https://profiles.wordpress.org/megainfo/">megainfo</a>,
+				<a href="https://profiles.wordpress.org/modemlooper/">modemlooper</a>,
+				<a href="https://profiles.wordpress.org/mpa4hu/">mpa4hu</a>,
+				<a href="https://profiles.wordpress.org/needle/">needle</a>,
+				<a href="https://profiles.wordpress.org/netweb/">netweb</a>,
+				<a href="https://profiles.wordpress.org/ninnypants/">ninnypants</a>,
+				Pietro Oliva,
+				<a href="https://profiles.wordpress.org/pross/">pross</a>,
+				<a href="https://profiles.wordpress.org/r-a-y/">r-a-y</a>,
+				<a href="https://profiles.wordpress.org/reactuate/">reactuate</a>,
+				<a href="https://profiles.wordpress.org/rodrigorznd/">rodrigorznd</a>,
+				<a href="https://profiles.wordpress.org/rogercoathup/">rogercoathup</a>,
+				<a href="https://profiles.wordpress.org/rzen/">rzen</a>,
+				<a href="https://profiles.wordpress.org/SergeyBiryukov/">SergeyBiryukov</a>,
+				<a href="https://profiles.wordpress.org/shanebp/">shanebp</a>,
+				<a href="https://profiles.wordpress.org/SlothLoveChunk/">SlothLoveChunk</a>,
+				<a href="https://profiles.wordpress.org/StijnDeWitt/">StijnDeWitt</a>,
+				<a href="https://profiles.wordpress.org/terraling/">terraling</a>,
+				<a href="https://profiles.wordpress.org/trishasalas/">trishasalas</a>,
+				<a href="https://profiles.wordpress.org/tw2113/">tw2113</a>,
+				<a href="https://profiles.wordpress.org/vanillalounge/">vanillalounge</a>.
 			</p>
 
-			<div class="return-to-dashboard">
-				<a href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), $this->settings_page ) ) ); ?>"><?php _e( 'Go to the BuddyPress Settings page', 'buddypress' ); ?></a>
-			</div>
+			<?php if ( current_user_can( $this->capability ) ) :?>
+				<div class="return-to-dashboard">
+					<a href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), $this->settings_page ) ) ); ?>"><?php _e( 'Go to the BuddyPress Settings page', 'buddypress' ); ?></a>
+				</div>
+			<?php endif;?>
 
 		</div>
 
@@ -609,9 +774,9 @@ class BP_Admin {
 endif; // class_exists check
 
 /**
- * Setup BuddyPress Admin
+ * Setup BuddyPress Admin.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
  * @uses BP_Admin
  */
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-adminbar.php b/wp-content/plugins/buddypress/bp-core/bp-core-adminbar.php
index 3fe2c05a377f1d028a0859b83ea2e30fb4e298ee..f92c396990f26127e14cadb3b1bfc43d23873c48 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-adminbar.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-adminbar.php
@@ -1,9 +1,9 @@
 <?php
 
 /**
- * BuddyPress Core Toolbar
+ * BuddyPress Core Toolbar.
  *
- * Handles the core functions related to the WordPress Toolbar
+ * Handles the core functions related to the WordPress Toolbar.
  *
  * @package BuddyPress
  * @subpackage Core
@@ -13,9 +13,10 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Adds the secondary BuddyPress area to the my-account menu
+ * Add the secondary BuddyPress area to the my-account menu.
+ *
+ * @since BuddyPress (1.6.0)
  *
- * @since BuddyPress 1.6
  * @global WP_Admin_Bar $wp_admin_bar
  */
 function bp_admin_bar_my_account_root() {
@@ -32,7 +33,7 @@ function bp_admin_bar_my_account_root() {
 		$wp_admin_bar->add_menu( array(
 			'parent'    => 'my-account',
 			'id'        => 'my-account-buddypress',
-			'title'     => __( 'My Account' ),
+			'title'     => __( 'My Account', 'buddypress' ),
 			'group'     => true,
 			'meta'      => array(
 				'class' => 'ab-sub-secondary'
@@ -43,22 +44,22 @@ function bp_admin_bar_my_account_root() {
 add_action( 'admin_bar_menu', 'bp_admin_bar_my_account_root', 100 );
 
 /**
- * Handle the Toolbar/BuddyBar business
+ * Handle the Toolbar/BuddyBar business.
  *
- * @since BuddyPress (1.2)
+ * @since BuddyPress (1.2.0)
  *
  * @global string $wp_version
  * @uses bp_get_option()
  * @uses is_user_logged_in()
  * @uses bp_use_wp_admin_bar()
  * @uses show_admin_bar()
- * @uses add_action() To hook 'bp_adminbar_logo' to 'bp_adminbar_logo'
- * @uses add_action() To hook 'bp_adminbar_login_menu' to 'bp_adminbar_menus'
- * @uses add_action() To hook 'bp_adminbar_account_menu' to 'bp_adminbar_menus'
- * @uses add_action() To hook 'bp_adminbar_thisblog_menu' to 'bp_adminbar_menus'
- * @uses add_action() To hook 'bp_adminbar_random_menu' to 'bp_adminbar_menus'
- * @uses add_action() To hook 'bp_core_admin_bar' to 'wp_footer'
- * @uses add_action() To hook 'bp_core_admin_bar' to 'admin_footer'
+ * @uses add_action() To hook 'bp_adminbar_logo' to 'bp_adminbar_logo'.
+ * @uses add_action() To hook 'bp_adminbar_login_menu' to 'bp_adminbar_menus'.
+ * @uses add_action() To hook 'bp_adminbar_account_menu' to 'bp_adminbar_menus'.
+ * @uses add_action() To hook 'bp_adminbar_thisblog_menu' to 'bp_adminbar_menus'.
+ * @uses add_action() To hook 'bp_adminbar_random_menu' to 'bp_adminbar_menus'.
+ * @uses add_action() To hook 'bp_core_admin_bar' to 'wp_footer'.
+ * @uses add_action() To hook 'bp_core_admin_bar' to 'admin_footer'.
  */
 function bp_core_load_admin_bar() {
 
@@ -88,9 +89,9 @@ function bp_core_load_admin_bar() {
 add_action( 'init', 'bp_core_load_admin_bar', 9 );
 
 /**
- * Handle the Toolbar CSS
+ * Handle the Toolbar CSS.
  *
- * @since BuddyPress 1.5
+ * @since BuddyPress (1.5.0)
  */
 function bp_core_load_admin_bar_css() {
 	global $wp_styles;
@@ -101,7 +102,7 @@ function bp_core_load_admin_bar_css() {
 	$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
 
 	// Toolbar styles
-	$stylesheet = BP_PLUGIN_URL . "bp-core/css/admin-bar{$min}.css";
+	$stylesheet = buddypress()->plugin_url . "bp-core/css/admin-bar{$min}.css";
 
 	wp_enqueue_style( 'bp-admin-bar', apply_filters( 'bp_core_admin_bar_css', $stylesheet ), array( 'admin-bar' ), bp_get_version() );
 	$wp_styles->add_data( 'bp-admin-bar', 'rtl', true );
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-avatars.php b/wp-content/plugins/buddypress/bp-core/bp-core-avatars.php
index 4962ea881d29f18de4bac66032bb54d3568607c0..93e7781079781db5ca87f42b1a946c56dac8f2b4 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-avatars.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-avatars.php
@@ -1,17 +1,19 @@
 <?php
 
 /**
- * BuddyPress Avatars
+ * BuddyPress Avatars.
  */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /***
- * Set up the constants we need for avatar support
+ * Set up the constants we need for avatar support.
  */
 function bp_core_set_avatar_constants() {
 
+	$bp = buddypress();
+
 	if ( !defined( 'BP_AVATAR_THUMB_WIDTH' ) )
 		define( 'BP_AVATAR_THUMB_WIDTH', 50 );
 
@@ -29,8 +31,6 @@ function bp_core_set_avatar_constants() {
 
 	if ( !defined( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE' ) ) {
 
-		$bp = buddypress();
-
 		if ( !isset( $bp->site_options['fileupload_maxk'] ) ) {
 			define( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE', 5120000 ); // 5mb
 		} else {
@@ -38,18 +38,17 @@ function bp_core_set_avatar_constants() {
 		}
 	}
 
-	if ( !defined( 'BP_AVATAR_DEFAULT' ) )
-		define( 'BP_AVATAR_DEFAULT', BP_PLUGIN_URL . 'bp-core/images/mystery-man.jpg' );
-
-	if ( !defined( 'BP_AVATAR_DEFAULT_THUMB' ) )
-		define( 'BP_AVATAR_DEFAULT_THUMB', BP_PLUGIN_URL . 'bp-core/images/mystery-man-50.jpg' );
-
 	if ( ! defined( 'BP_SHOW_AVATARS' ) ) {
 		define( 'BP_SHOW_AVATARS', bp_get_option( 'show_avatars' ) );
 	}
 }
 add_action( 'bp_init', 'bp_core_set_avatar_constants', 3 );
 
+/**
+ * Set up global variables related to avatars.
+ *
+ * @since BuddyPress (1.5.0)
+ */
 function bp_core_set_avatar_globals() {
 	$bp = buddypress();
 
@@ -68,8 +67,8 @@ function bp_core_set_avatar_globals() {
 	$bp->avatar->original_max_filesize = BP_AVATAR_ORIGINAL_MAX_FILESIZE;
 
 	// Defaults
-	$bp->avatar->thumb->default = BP_AVATAR_DEFAULT_THUMB;
-	$bp->avatar->full->default  = BP_AVATAR_DEFAULT;
+	$bp->avatar->thumb->default = bp_core_avatar_default_thumb();
+	$bp->avatar->full->default  = bp_core_avatar_default();
 
 	// These have to be set on page load in order to avoid infinite filter loops at runtime
 	$bp->avatar->upload_path = bp_core_avatar_upload_path();
@@ -92,14 +91,87 @@ function bp_core_set_avatar_globals() {
 add_action( 'bp_setup_globals', 'bp_core_set_avatar_globals' );
 
 /**
- * bp_core_fetch_avatar()
+ * Get an avatar for a BuddyPress object.
+ *
+ * Supports avatars for users, groups, and blogs by default, but can be
+ * extended to support custom components as well.
  *
- * Fetches an avatar from a BuddyPress object. Supports user/group/blog as
- * default, but can be extended to include your own custom components too.
+ * This function gives precedence to locally-uploaded avatars. When a local
+ * avatar is not found, Gravatar is queried. To disable Gravatar fallbacks
+ * locally:
+ *    add_filter( 'bp_core_fetch_avatar_no_grav', '__return_true' );
  *
- * @global $current_blog WordPress global containing information and settings for the current blog being viewed.
- * @param array $args Determine the output of this function
- * @return string Formatted HTML <img> element, or raw avatar URL based on $html arg
+ * @param array $args {
+ *     An array of arguments. All arguments are technically optional; some
+ *     will, if not provided, be auto-detected by bp_core_fetch_avatar(). This
+ *     auto-detection is described more below, when discussing specific
+ *     arguments.
+ *
+ *     @type int|bool $item_id The numeric ID of the item for which you're
+ *           requesting an avatar (eg, a user ID). If no 'item_id' is present,
+ *           the function attempts to infer an ID from the 'object' + the
+ *           current context: if 'object' is 'user' and the current page is a
+ *           user page, 'item_id' will default to the displayed user ID; if
+ *           'group' and on a group page, to the current group ID; if 'blog',
+ *           to the current blog's ID. If no 'item_id' can be determined in
+ *           this way, the function returns false. Default: false.
+ *     @type string $object The kind of object for which you're getting an
+ *           avatar. BuddyPress natively supports three options: 'user',
+ *           'group', 'blog'; a plugin may register more.  Default: 'user'.
+ *     @type string $type When a new avatar is uploaded to BP, 'thumb' and
+ *           'full' versions are saved. This parameter specifies whether you'd
+ *           like the 'full' or smaller 'thumb' avatar. Default: 'thumb'.
+ *     @type string|bool $avatar_dir The name of the subdirectory where the
+ *           requested avatar should be found. If no value is passed,
+ *           'avatar_dir' is inferred from 'object': 'user' becomes 'avatars',
+ *           'group' becomes 'group-avatars', 'blog' becomes 'blog-avatars'.
+ *           Remember that this string denotes a subdirectory of BP's main
+ *           avatar directory (usually based on {@link wp_upload_dir()}); it's a
+ *           string like 'group-avatars' rather than the full directory path.
+ *           Generally, it'll only be necessary to override the default value if
+ *           storing avatars in a non-default location. Defaults to false
+ *           (auto-detected).
+ *     @type int|bool $width Requested avatar width. The unit is px. This value
+ *           is used to build the 'width' attribute for the <img> element. If
+ *           no value is passed, BP uses the global avatar width for this
+ *           avatar type. Default: false (auto-detected).
+ *     @type int|bool $height Requested avatar height. The unit is px. This
+ *           value is used to build the 'height' attribute for the <img>
+ *           element. If no value is passed, BP uses the global avatar height
+ *           for this avatar type. Default: false (auto-detected).
+ *     @type string $class The CSS class for the <img> element. Note that BP
+ *           uses the 'avatar' class fairly extensively in its default styling,
+ *           so if you plan to pass a custom value, consider appending it to
+ *           'avatar' (eg 'avatar foo') rather than replacing it altogether.
+ *           Default: 'avatar'.
+ *     @type string|bool $css_id The CSS id for the <img> element.
+ *           Default: false.
+ *     @type string $title The title attribute for the <img> element.
+ *           Default: false.
+ *     @type string $alt The alt attribute for the <img> element. In BP, this
+ *           value is generally passed by the wrapper functions, where the data
+ *           necessary for concatenating the string is at hand; see
+ *           {@link bp_get_activity_avatar()} for an example. Default: ''.
+ *     @type string|bool $email An email to use in Gravatar queries. Unless
+ *           otherwise configured, BP uses Gravatar as a fallback for avatars
+ *           that are not provided locally. Gravatar's API requires using a hash
+ *           of the user's email address; this argument provides it. If not
+ *           provided, the function will infer it: for users, by getting the
+ *           user's email from the database, for groups/blogs, by concatenating
+ *           "{$item_id}-{$object}@{bp_get_root_domain()}". The user query adds
+ *           overhead, so it's recommended that wrapper functions provide a
+ *           value for 'email' when querying user IDs. Default: false.
+ *     @type bool $no_grav Whether to disable the default Gravatar fallback.
+ *           By default, BP will fall back on Gravatar when it cannot find a
+ *           local avatar. In some cases, this may be undesirable, in which
+ *           case 'no_grav' should be set to true. To disable Gravatar
+ *           fallbacks globally, see the 'bp_core_fetch_avatar_no_grav' filter.
+ *           Default: false.
+ *     @type bool $html Whether to return an <img> HTML element, vs a raw URL
+ *           to an avatar. If false, <img>-specific arguments (like 'css_id')
+ *           will be ignored. Default: true.
+ * }
+ * @return string Formatted HTML <img> element, or raw avatar URL based on $html arg.
  */
 function bp_core_fetch_avatar( $args = '' ) {
 
@@ -361,7 +433,7 @@ function bp_core_fetch_avatar( $args = '' ) {
 		if ( empty( $bp->grav_default->{$object} ) ) {
 			$default_grav = 'wavatar';
 		} else if ( 'mystery' == $bp->grav_default->{$object} ) {
-			$default_grav = apply_filters( 'bp_core_mysteryman_src', bp_core_avatar_default(), $grav_size );
+			$default_grav = apply_filters( 'bp_core_mysteryman_src', 'mm', $grav_size );
 		} else {
 			$default_grav = $bp->grav_default->{$object};
 		}
@@ -393,7 +465,7 @@ function bp_core_fetch_avatar( $args = '' ) {
 
 	// No avatar was found, and we've been told not to use a gravatar.
 	} else {
-		$gravatar = apply_filters( "bp_core_default_avatar_$object", BP_PLUGIN_URL . 'bp-core/images/mystery-man.jpg', $params );
+		$gravatar = apply_filters( "bp_core_default_avatar_$object", bp_core_avatar_default( 'local' ), $params );
 	}
 
 	if ( true === $html ) {
@@ -404,15 +476,19 @@ function bp_core_fetch_avatar( $args = '' ) {
 }
 
 /**
- * Delete an existing avatar
- *
- * Accepted values for $args are:
- *  item_id - item id which relates to the object type.
- *  object - the objetc type user, group, blog, etc.
- *  avatar_dir - The directory where the avatars to be uploaded.
+ * Delete an existing avatar.
  *
- * @param mixed $args
- * @return bool Success/failure
+ * @param array $args {
+ *     Array of function parameters.
+ *     @type bool|int $item_id ID of the item whose avatar you're deleting.
+ *           Defaults to the current item of type $object.
+ *     @type string $object Object type of the item whose avatar you're
+ *           deleting. 'user', 'group', 'blog', or custom. Default: 'user'.
+ *     @type bool|string $avatar_dir Subdirectory where avatar is located.
+ *           Default: false, which falls back on the default location
+ *           corresponding to the $object.
+ * }
+ * @return bool True on success, false on failure.
  */
 function bp_core_delete_existing_avatar( $args = '' ) {
 
@@ -472,17 +548,20 @@ function bp_core_delete_existing_avatar( $args = '' ) {
 }
 
 /**
- * Handles avatar uploading.
+ * Handle avatar uploading.
  *
- * The functions starts off by checking that the file has been uploaded properly using bp_core_check_avatar_upload().
- * It then checks that the file size is within limits, and that it has an accepted file extension (jpg, gif, png).
- * If everything checks out, crop the image and move it to its real location.
+ * The functions starts off by checking that the file has been uploaded
+ * properly using bp_core_check_avatar_upload(). It then checks that the file
+ * size is within limits, and that it has an accepted file extension (jpg, gif,
+ * png). If everything checks out, crop the image and move it to its real
+ * location.
  *
- * @param array $file The appropriate entry the from $_FILES superglobal.
- * @param string $upload_dir_filter A filter to be applied to upload_dir
- * @return bool Success/failure
  * @see bp_core_check_avatar_upload()
  * @see bp_core_check_avatar_type()
+ *
+ * @param array $file The appropriate entry the from $_FILES superglobal.
+ * @param string $upload_dir_filter A filter to be applied to 'upload_dir'.
+ * @return bool True on success, false on failure.
  */
 function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
 
@@ -598,7 +677,7 @@ function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
 }
 
 /**
- * Crop an uploaded avatar
+ * Crop an uploaded avatar.
  *
  * $args has the following parameters:
  *  object - What component the avatar is for, e.g. "user"
@@ -610,8 +689,23 @@ function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
  *  crop_x - The horizontal starting point of the crop
  *  crop_y - The vertical starting point of the crop
  *
- * @param mixed $args
- * @return bool Success/failure
+ * @param array $args {
+ *     Array of function parameters.
+ *     @type string $object Object type of the item whose avatar you're
+ *           handling. 'user', 'group', 'blog', or custom. Default: 'user'.
+ *     @type string $avatar_dir Subdirectory where avatar should be stored.
+ *           Default: 'avatars'.
+ *     @type bool|int $item_id ID of the item that the avatar belongs to.
+ *     @type bool|string $original_file Absolute papth to the original avatar
+ *           file.
+ *     @type int $crop_w Crop width. Default: the global 'full' avatar width,
+ *           as retrieved by bp_core_avatar_full_width().
+ *     @type int $crop_h Crop height. Default: the global 'full' avatar height,
+ *           as retrieved by bp_core_avatar_full_height().
+ *     @type int $crop_x The horizontal starting point of the crop. Default: 0.
+ *     @type int $crop_y The vertical starting point of the crop. Default: 0.
+ * }
+ * @return bool True on success, false on failure.
  */
 function bp_core_avatar_handle_crop( $args = '' ) {
 
@@ -656,7 +750,25 @@ function bp_core_avatar_handle_crop( $args = '' ) {
 	require_once( ABSPATH . '/wp-admin/includes/file.php' );
 
 	// Delete the existing avatar files for the object
-	bp_core_delete_existing_avatar( array( 'object' => $object, 'avatar_path' => $avatar_folder_dir ) );
+	$existing_avatar = bp_core_fetch_avatar( array(
+		'object'  => $object,
+		'item_id' => $item_id,
+		'html' => false,
+	) );
+
+	if ( ! empty( $existing_avatar ) ) {
+		// Check that the new avatar doesn't have the same name as the
+		// old one before deleting
+		$upload_dir           = wp_upload_dir();
+		$existing_avatar_path = str_replace( $upload_dir['baseurl'], '', $existing_avatar );
+		$new_avatar_path      = str_replace( $upload_dir['basedir'], '', $original_file );
+
+		if ( $existing_avatar_path !== $new_avatar_path ) {
+			bp_core_delete_existing_avatar( array( 'object' => $object, 'item_id' => $item_id, 'avatar_path' => $avatar_folder_dir ) );
+		}
+	}
+
+
 
 	// Make sure we at least have a width and height for cropping
 	if ( empty( $crop_w ) ) {
@@ -690,18 +802,16 @@ function bp_core_avatar_handle_crop( $args = '' ) {
 }
 
 /**
- * bp_core_fetch_avatar_filter()
+ * Replace default WordPress avatars with BP avatars, if available.
  *
- * Attempts to filter get_avatar function and let BuddyPress have a go
- * at finding an avatar that may have been uploaded locally.
+ * Filters 'get_avatar'.
  *
- * @global array $authordata
- * @param string $avatar The result of get_avatar from before-filter
- * @param int|string|object $user A user ID, email address, or comment object
- * @param int $size Size of the avatar image (thumb/full)
- * @param string $default URL to a default image to use if no avatar is available
- * @param string $alt Alternate text to use in image tag. Defaults to blank
- * @return string
+ * @param string $avatar The avatar path passed to 'get_avatar'.
+ * @param int|string|object $user A user ID, email address, or comment object.
+ * @param int $size Size of the avatar image ('thumb' or 'full').
+ * @param string $default URL to a default image to use if no avatar is available.
+ * @param string $alt Alternate text to use in image tag. Default: ''.
+ * @return string BP avatar path, if found; else the original avatar path.
  */
 function bp_core_fetch_avatar_filter( $avatar, $user, $size, $default, $alt = '' ) {
 	global $pagenow;
@@ -733,8 +843,21 @@ function bp_core_fetch_avatar_filter( $avatar, $user, $size, $default, $alt = ''
 		$alt = sprintf( __( 'Avatar of %s', 'buddypress' ), bp_core_get_user_displayname( $id ) );
 	}
 
+	// Use the 'thumb' type, unless the requested width is bigger than
+	// BP's thumb width.
+	$type = 'thumb';
+	if ( (int) $size > bp_core_avatar_thumb_width() ) {
+		$type = 'full';
+	}
+
 	// Let BuddyPress handle the fetching of the avatar
-	$bp_avatar = bp_core_fetch_avatar( array( 'item_id' => $id, 'width' => $size, 'height' => $size, 'alt' => $alt ) );
+	$bp_avatar = bp_core_fetch_avatar( array(
+		'item_id' => $id,
+		'type'    => $type,
+		'width'   => $size,
+		'height'  => $size,
+		'alt'     => $alt,
+	) );
 
 	// If BuddyPress found an avatar, use it. If not, use the result of get_avatar
 	return ( !$bp_avatar ) ? $avatar : $bp_avatar;
@@ -742,10 +865,10 @@ function bp_core_fetch_avatar_filter( $avatar, $user, $size, $default, $alt = ''
 add_filter( 'get_avatar', 'bp_core_fetch_avatar_filter', 10, 5 );
 
 /**
- * Has the current avatar upload generated an error?
+ * Is the current avatar upload error-free?
  *
- * @param array $file
- * @return bool
+ * @param array $file The $_FILES array.
+ * @return bool True if no errors are found. False if there are errors.
  */
 function bp_core_check_avatar_upload( $file ) {
 	if ( isset( $file['error'] ) && $file['error'] )
@@ -757,8 +880,8 @@ function bp_core_check_avatar_upload( $file ) {
 /**
  * Is the file size of the current avatar upload permitted?
  *
- * @param array $file
- * @return bool
+ * @param array $file The $_FILES array.
+ * @return bool True if the avatar is under the size limit, otherwise false.
  */
 function bp_core_check_avatar_size( $file ) {
 	if ( $file['file']['size'] > bp_core_avatar_original_max_filesize() )
@@ -772,8 +895,8 @@ function bp_core_check_avatar_size( $file ) {
  *
  * Permitted file types are JPG, GIF and PNG.
  *
- * @param string $file
- * @return bool
+ * @param array $file The $_FILES array.
+ * @return bool True if the file extension is permitted, otherwise false.
  */
 function bp_core_check_avatar_type($file) {
 	if ( ( !empty( $file['file']['type'] ) && !preg_match('/(jpe?g|gif|png)$/i', $file['file']['type'] ) ) || !preg_match( '/(jpe?g|gif|png)$/i', $file['file']['name'] ) )
@@ -783,7 +906,7 @@ function bp_core_check_avatar_type($file) {
 }
 
 /**
- * Fetches data from the BP root blog's upload directory.
+ * Fetch data from the BP root blog's upload directory.
  *
  * Handy for multisite instances because all uploads are made on the BP root
  * blog and we need to query the BP root blog for the upload directory data.
@@ -791,13 +914,13 @@ function bp_core_check_avatar_type($file) {
  * This function ensures that we only need to use {@link switch_to_blog()}
  * once to get what we need.
  *
- * @since BuddyPress (1.8)
+ * @since BuddyPress (1.8.0)
  *
  * @uses wp_upload_dir()
  *
- * @param string $type The variable we want to return from the $bp->avatars object.
- *  Only 'upload_path' and 'url' are supported.
- * @return string
+ * @param string $type The variable we want to return from the $bp->avatars
+ *        object. Only 'upload_path' and 'url' are supported. Default: 'upload_path'.
+ * @return string The avatar upload directory path.
  */
 function bp_core_get_upload_dir( $type = 'upload_path' ) {
 	$bp = buddypress();
@@ -875,35 +998,34 @@ function bp_core_get_upload_dir( $type = 'upload_path' ) {
 }
 
 /**
- * bp_core_avatar_upload_path()
- *
- * Returns the absolute upload path for the WP installation
+ * Get the absolute upload path for the WP installation.
  *
  * @uses wp_upload_dir To get upload directory info
- * @return string Absolute path to WP upload directory
+ *
+ * @return string Absolute path to WP upload directory.
  */
 function bp_core_avatar_upload_path() {
 	return apply_filters( 'bp_core_avatar_upload_path', bp_core_get_upload_dir() );
 }
 
 /**
- * bp_core_avatar_url()
+ * Get the raw base URL for root site upload location.
  *
- * Returns the raw base URL for root site upload location
+ * @uses wp_upload_dir To get upload directory info.
  *
- * @uses wp_upload_dir To get upload directory info
- * @return string Full URL to current upload location
+ * @return string Full URL to current upload location.
  */
 function bp_core_avatar_url() {
 	return apply_filters( 'bp_core_avatar_url', bp_core_get_upload_dir( 'url' ) );
 }
 
 /**
- * Check if a given user ID has an uploaded avatar
+ * Check if a given user ID has an uploaded avatar.
  *
- * @since BuddyPress (1.0)
- * @param int $user_id
- * @return boolean
+ * @since BuddyPress (1.0.0)
+ *
+ * @param int $user_id ID of the user whose avatar is being checked.
+ * @return bool True if the user has uploaded a local avatar. Otherwise false.
  */
 function bp_get_user_has_avatar( $user_id = 0 ) {
 
@@ -911,21 +1033,22 @@ function bp_get_user_has_avatar( $user_id = 0 ) {
 		$user_id = bp_displayed_user_id();
 
 	$retval = false;
-	if ( bp_core_fetch_avatar( array( 'item_id' => $user_id, 'no_grav' => true, 'html' => false ) ) != bp_core_avatar_default() )
+	if ( bp_core_fetch_avatar( array( 'item_id' => $user_id, 'no_grav' => true, 'html' => false ) ) != bp_core_avatar_default( 'local' ) )
 		$retval = true;
 
 	return (bool) apply_filters( 'bp_get_user_has_avatar', $retval, $user_id );
 }
 
 /**
- * Utility function for fetching an avatar dimension setting
+ * Utility function for fetching an avatar dimension setting.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param string $type 'thumb' for thumbs, otherwise full
- * @param string $h_or_w 'height' for height, otherwise width
- * @return int $dim The dimension
+ * @param string $type Dimension type you're fetching dimensions for. 'thumb'
+ *        or 'full'. Default: 'thumb'.
+ * @param string $h_or_w Which dimension is being fetched. 'height' or 'width'.
+ *        Default: 'height'.
+ * @return int $dim The dimension.
  */
 function bp_core_avatar_dimension( $type = 'thumb', $h_or_w = 'height' ) {
 	$bp  = buddypress();
@@ -935,97 +1058,136 @@ function bp_core_avatar_dimension( $type = 'thumb', $h_or_w = 'height' ) {
 }
 
 /**
- * Get the avatar thumb width setting
+ * Get the 'thumb' avatar width setting.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int The thumb width
+ * @return int The 'thumb' width.
  */
 function bp_core_avatar_thumb_width() {
 	return apply_filters( 'bp_core_avatar_thumb_width', bp_core_avatar_dimension( 'thumb', 'width' ) );
 }
 
 /**
- * Get the avatar thumb height setting
+ * Get the 'thumb' avatar height setting.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int The thumb height
+ * @return int The 'thumb' height.
  */
 function bp_core_avatar_thumb_height() {
 	return apply_filters( 'bp_core_avatar_thumb_height', bp_core_avatar_dimension( 'thumb', 'height' ) );
 }
 
 /**
- * Get the avatar full width setting
+ * Get the 'full' avatar width setting
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int The full width
+ * @return int The 'full' width.
  */
 function bp_core_avatar_full_width() {
 	return apply_filters( 'bp_core_avatar_full_width', bp_core_avatar_dimension( 'full', 'width' ) );
 }
 
 /**
- * Get the avatar full height setting
+ * Get the 'full' avatar height setting.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int The full height
+ * @return int The 'full' height.
  */
 function bp_core_avatar_full_height() {
 	return apply_filters( 'bp_core_avatar_full_height', bp_core_avatar_dimension( 'full', 'height' ) );
 }
 
 /**
- * Get the max width for original avatar uploads
+ * Get the max width for original avatar uploads.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int The width
+ * @return int The max width for original avatar uploads.
  */
 function bp_core_avatar_original_max_width() {
 	return apply_filters( 'bp_core_avatar_original_max_width', (int) buddypress()->avatar->original_max_width );
 }
 
 /**
- * Get the max filesize for original avatar uploads
+ * Get the max filesize for original avatar uploads.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int The filesize
+ * @return int The max filesize for original avatar uploads.
  */
 function bp_core_avatar_original_max_filesize() {
 	return apply_filters( 'bp_core_avatar_original_max_filesize', (int) buddypress()->avatar->original_max_filesize );
 }
 
 /**
- * Get the default avatar
+ * Get the URL of the 'full' default avatar.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int The URL of the default avatar
+ * @param string $type 'local' if the fallback should be the locally-hosted
+ *        version of the mystery-man, 'gravatar' if the fallback should be
+ *        Gravatar's version. Default: 'gravatar'.
+ * @return string The URL of the default avatar.
  */
-function bp_core_avatar_default() {
-	return apply_filters( 'bp_core_avatar_default', buddypress()->avatar->full->default );
+function bp_core_avatar_default( $type = 'gravatar' ) {
+	// Local override
+	if ( defined( 'BP_AVATAR_DEFAULT' ) ) {
+		$avatar = BP_AVATAR_DEFAULT;
+
+	// Use the local default image
+	} else if ( 'local' === $type ) {
+		$avatar = buddypress()->plugin_url . 'bp-core/images/mystery-man.jpg';
+
+	// Use Gravatar's mystery man as fallback
+	} else {
+		if ( is_ssl() ) {
+			$host = 'https://secure.gravatar.com';
+		} else {
+			$host = 'http://www.gravatar.com';
+		}
+
+		$avatar = $host . '/avatar/00000000000000000000000000000000?d=mm&amp;s=' . bp_core_avatar_full_width();
+	}
+
+	return apply_filters( 'bp_core_avatar_default', $avatar );
 }
 
 /**
- * Get the default avatar thumb
+ * Get the URL of the 'thumb' default avatar.
+ *
+ * Uses Gravatar's mystery-man avatar, unless BP_AVATAR_DEFAULT_THUMB has been
+ * defined.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int The URL of the default avatar thumb
+ * @param string $type 'local' if the fallback should be the locally-hosted
+ *        version of the mystery-man, 'gravatar' if the fallback should be
+ *        Gravatar's version. Default: 'gravatar'.
+ * @return string The URL of the default avatar thumb.
  */
-function bp_core_avatar_default_thumb() {
-	return apply_filters( 'bp_core_avatar_thumb', buddypress()->avatar->thumb->default );
+function bp_core_avatar_default_thumb( $type = 'gravatar' ) {
+	// Local override
+	if ( defined( 'BP_AVATAR_DEFAULT_THUMB' ) ) {
+		$avatar = BP_AVATAR_DEFAULT_THUMB;
+
+	// Use the local default image
+	} else if ( 'local' === $type ) {
+		$avatar = buddypress()->plugin_url . 'bp-core/images/mystery-man-50.jpg';
+
+	// Use Gravatar's mystery man as fallback
+	} else {
+		if ( is_ssl() ) {
+			$host = 'https://secure.gravatar.com';
+		} else {
+			$host = 'http://www.gravatar.com';
+		}
+
+		$avatar = $host . '/avatar/00000000000000000000000000000000?d=mm&amp;s=' . bp_core_avatar_thumb_width();
+	}
+
+	return apply_filters( 'bp_core_avatar_thumb', $avatar );
 }
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-buddybar.php b/wp-content/plugins/buddypress/bp-core/bp-core-buddybar.php
index 263dbb46f74ab8767947933cf067dd4e80adf19d..ed5edf36c263930da1e02acf6aa6dda8cc7dd73d 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-buddybar.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-buddybar.php
@@ -1,21 +1,41 @@
 <?php
 
 /**
- * Core BuddyPress Navigational Functions
+ * Core BuddyPress Navigational Functions.
  *
  * @package BuddyPress
  * @subpackage Core
- * @todo Deprecate BuddyBar functions
+ * @todo Deprecate BuddyBar functions.
  */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Adds a navigation item to the main navigation array used in BuddyPress themes.
+ * Add an item to the main BuddyPress navigation array.
  *
- * @package BuddyPress Core
- * @global BuddyPress $bp The one true BuddyPress instance
+ * @global BuddyPress $bp The one true BuddyPress instance.
+ *
+ * @param array $args {
+ *     Array describing the new nav item.
+ *     @type string $name Display name for the nav item.
+ *     @type string $slug Unique URL slug for the nav item.
+ *     @type bool|string $item_css_id Optional. 'id' attribute for the nav
+ *           item. Default: the value of $slug.
+ *     @type bool $show_for_displayed_user Optional. Whether the nav item
+ *           should be visible when viewing a member profile other than your
+ *           own. Default: true.
+ *     @type bool $site_admin_only Optional. Whether the nav item should be
+ *           visible only to site admins (those with the 'bp_moderate' cap).
+ *           Default: false.
+ *     @type int $position Optional. Numerical index specifying where the item
+ *           should appear in the nav array. Default: 99.
+ *     @type callable $screen_function The callback function that will run
+ *           when the nav item is clicked.
+ *     @type bool|string $default_subnav_slug Optional. The slug of the default
+ *           subnav item to select when the nav item is clicked.
+ * }
+ * @return bool|null Returns false on failure.
  */
 function bp_core_new_nav_item( $args = '' ) {
 	global $bp;
@@ -97,10 +117,17 @@ function bp_core_new_nav_item( $args = '' ) {
 }
 
 /**
- * Modify the default subnav item to load when a top level nav item is clicked.
+ * Modify the default subnav item that loads when a top level nav item is clicked.
  *
- * @package BuddyPress Core
- * @global BuddyPress $bp The one true BuddyPress instance
+ * @global BuddyPress $bp The one true BuddyPress instance.
+ *
+ * @param array $args {
+ *     @type string $parent_slug The slug of the nav item whose default is
+ *           being changed.
+ *     @type callable $screen_function The new default callback function that
+ *           will run when the nav item is clicked.
+ *     @type string $subnav_slug The slug of the new default subnav item.
+ * }
  */
 function bp_core_new_nav_default( $args = '' ) {
 	global $bp;
@@ -163,11 +190,14 @@ function bp_core_new_nav_default( $args = '' ) {
 }
 
 /**
- * We can only sort nav items by their position integer at a later point in time, once all
- * plugins have registered their navigation items.
+ * Sort the navigation menu items.
+ *
+ * The sorting is split into a separate function because it can only happen
+ * after all plugins have had a chance to register their navigation items.
  *
- * @package BuddyPress Core
  * @global BuddyPress $bp The one true BuddyPress instance
+ *
+ * @return bool|null Returns false on failure.
  */
 function bp_core_sort_nav_items() {
 	global $bp;
@@ -197,10 +227,34 @@ add_action( 'wp_head',    'bp_core_sort_nav_items' );
 add_action( 'admin_head', 'bp_core_sort_nav_items' );
 
 /**
- * Adds a navigation item to the sub navigation array used in BuddyPress themes.
+ * Add a subnav item to the BuddyPress navigation.
  *
- * @package BuddyPress Core
- * @global BuddyPress $bp The one true BuddyPress instance
+ * @global BuddyPress $bp The one true BuddyPress instance.
+ *
+ * @param array $args {
+ *     Array describing the new subnav item.
+ *     @type string $name Display name for the subnav item.
+ *     @type string $slug Unique URL slug for the subnav item.
+ *     @type string $parent_slug Slug of the top-level nav item under which the
+ *           new subnav item should be added.
+ *     @type string $parent_url URL of the parent nav item.
+ *     @type bool|string $item_css_id Optional. 'id' attribute for the nav
+ *           item. Default: the value of $slug.
+ *     @type bool $user_has_access Optional. True if the logged-in user has
+ *           access to the subnav item, otherwise false. Can be set dynamically
+ *           when registering the subnav; eg, use bp_is_my_profile() to restrict
+ *           access to profile owners only. Default: true.
+ *     @type bool $site_admin_only Optional. Whether the nav item should be
+ *           visible only to site admins (those with the 'bp_moderate' cap).
+ *           Default: false.
+ *     @type int $position Optional. Numerical index specifying where the item
+ *           should appear in the subnav array. Default: 90.
+ *     @type callable $screen_function The callback function that will run
+ *           when the nav item is clicked.
+ *     @type string $link Optional. The URL that the subnav item should point
+ *           to. Defaults to a value generated from the $parent_url + $slug.
+ * }
+ * @return bool|null Returns false on failure.
  */
 function bp_core_new_subnav_item( $args = '' ) {
 	global $bp;
@@ -318,6 +372,13 @@ function bp_core_new_subnav_item( $args = '' ) {
 	}
 }
 
+/**
+ * Sort all subnavigation arrays.
+ *
+ * @global BuddyPress $bp The one true BuddyPress instance
+ *
+ * @return bool|null Returns false on failure.
+ */
 function bp_core_sort_subnav_items() {
 	global $bp;
 
@@ -349,13 +410,14 @@ add_action( 'wp_head',    'bp_core_sort_subnav_items' );
 add_action( 'admin_head', 'bp_core_sort_subnav_items' );
 
 /**
- * Determines whether a given nav item has subnav items
+ * Check whether a given nav item has subnav items.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param string $nav_item The id of the top-level nav item whose nav items you're checking
- * @return bool $has_subnav True if the nav item is found and has subnav items; false otherwise
+ * @param string $nav_item The slug of the top-level nav item whose subnav
+ *        items you're checking. Default: the current component slug.
+ * @return bool $has_subnav True if the nav item is found and has subnav
+ *        items; false otherwise.
  */
 function bp_nav_item_has_subnav( $nav_item = '' ) {
 	global $bp;
@@ -369,11 +431,10 @@ function bp_nav_item_has_subnav( $nav_item = '' ) {
 }
 
 /**
- * Removes a navigation item from the sub navigation array used in BuddyPress themes.
+ * Remove a nav item from the navigation array.
  *
- * @package BuddyPress Core
- * @param int $parent_id The id of the parent navigation item.
- * @param bool|string false if the parent item doesn't exist or $slug the slug of the sub navigation item.
+ * @param int $parent_id The slug of the parent navigation item.
+ * @param bool Returns false on failure, ie if the nav item can't be found.
  */
 function bp_core_remove_nav_item( $parent_id ) {
 	global $bp;
@@ -399,11 +460,10 @@ function bp_core_remove_nav_item( $parent_id ) {
 }
 
 /**
- * Removes a navigation item from the sub navigation array used in BuddyPress themes.
+ * Remove a subnav item from the navigation array.
  *
- * @package BuddyPress Core
- * @param string $parent_id The id of the parent navigation item.
- * @param string $slug The slug of the sub navigation item.
+ * @param string $parent_id The slug of the parent navigation item.
+ * @param string $slug The slug of the subnav item to be removed.
  */
 function bp_core_remove_subnav_item( $parent_id, $slug ) {
 	global $bp;
@@ -424,11 +484,11 @@ function bp_core_remove_subnav_item( $parent_id, $slug ) {
 }
 
 /**
- * Clear the subnav items for a specific nav item.
+ * Clear all subnav items from a specific nav item.
  *
- * @package BuddyPress Core
- * @param string $parent_id The id of the parent navigation item.
- * @global BuddyPress $bp The one true BuddyPress instance
+ * @global BuddyPress $bp The one true BuddyPress instance.
+ *
+ * @param string $parent_slug The slug of the parent navigation item.
  */
 function bp_core_reset_subnav_items( $parent_slug ) {
 	global $bp;
@@ -436,8 +496,13 @@ function bp_core_reset_subnav_items( $parent_slug ) {
 	unset( $bp->bp_options_nav[$parent_slug] );
 }
 
-/** Template functions ********************************************************/
+/** BuddyBar Template functions ***********************************************/
 
+/**
+ * Wrapper function for rendering the BuddyBar.
+ *
+ * @return bool|null Returns false if the BuddyBar is disabled.
+ */
 function bp_core_admin_bar() {
 	global $bp;
 
@@ -465,12 +530,20 @@ function bp_core_admin_bar() {
 	$bp->doing_admin_bar = false;
 }
 
-// **** Default BuddyPress Toolbar logo ********
+/**
+ * Output the BuddyBar logo.
+ */
 function bp_adminbar_logo() {
 	echo '<a href="' . bp_get_root_domain() . '" id="admin-bar-logo">' . get_blog_option( bp_get_root_blog_id(), 'blogname' ) . '</a>';
 }
 
-// **** "Log In" and "Sign Up" links (Visible when not logged in) ********
+/**
+ * Output the "Log In" and "Sign Up" names to the BuddyBar.
+ *
+ * Visible only to visitors who are not logged in.
+ *
+ * @return bool|null Returns false if the current user is logged in.
+ */
 function bp_adminbar_login_menu() {
 
 	if ( is_user_logged_in() )
@@ -483,8 +556,11 @@ function bp_adminbar_login_menu() {
 		echo '<li class="bp-signup no-arrow"><a href="' . bp_get_signup_page() . '">' . __( 'Sign Up', 'buddypress' ) . '</a></li>';
 }
 
-
-// **** "My Account" Menu ******
+/**
+ * Output the My Account BuddyBar menu.
+ *
+ * @return bool|null Returns false on failure.
+ */
 function bp_adminbar_account_menu() {
 	global $bp;
 
@@ -557,8 +633,11 @@ function bp_adminbar_thisblog_menu() {
 	}
 }
 
-
-// **** "Random" Menu (visible when not logged in) ********
+/**
+ * Output the Random BuddyBar menu.
+ *
+ * Not visible for logged-in users.
+ */
 function bp_adminbar_random_menu() {
 ?>
 
@@ -592,14 +671,14 @@ function bp_adminbar_random_menu() {
  *
  * This is a direct copy of WP's private _get_admin_bar_pref()
  *
- * @since BuddyPress (1.5)
- *
- * @param string $context Context of this preference check, either 'admin' or 'front'.
- * @param int $user Optional. ID of the user to check, defaults to 0 for current user.
+ * @since BuddyPress (1.5.0)
  *
  * @uses get_user_option()
  *
- * @return bool Whether the Toolbar should be showing for this user.
+ * @param string $context Context of this preference check. 'admin' or 'front'.
+ * @param int $user Optional. ID of the user to check. Default: 0 (which falls
+ *        back to the logged-in user's ID).
+ * @return bool True if the toolbar should be showing for this user.
  */
 function bp_get_admin_bar_pref( $context, $user = 0 ) {
 	$pref = get_user_option( "show_admin_bar_{$context}", $user );
@@ -610,7 +689,7 @@ function bp_get_admin_bar_pref( $context, $user = 0 ) {
 }
 
 /**
- * Handle the BuddyBar CSS
+ * Enqueue the BuddyBar CSS.
  */
 function bp_core_load_buddybar_css() {
 	global $wp_styles;
@@ -620,10 +699,11 @@ function bp_core_load_buddybar_css() {
 
 	$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
 
-	if ( file_exists( get_stylesheet_directory() . '/_inc/css/adminbar.css' ) ) // Backwards compatibility
+	if ( file_exists( get_stylesheet_directory() . '/_inc/css/adminbar.css' ) ) { // Backwards compatibility
 		$stylesheet = get_stylesheet_directory_uri() . '/_inc/css/adminbar.css';
-	else
-		$stylesheet = BP_PLUGIN_URL . "bp-core/css/buddybar{$min}.css";
+	} else {
+		$stylesheet = buddypress()->plugin_url . "bp-core/css/buddybar{$min}.css";
+	}
 
 	wp_enqueue_style( 'bp-admin-bar', apply_filters( 'bp_core_buddybar_rtl_css', $stylesheet ), array(), bp_get_version() );
 	$wp_styles->add_data( 'bp-admin-bar', 'rtl', true );
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-cache.php b/wp-content/plugins/buddypress/bp-core/bp-core-cache.php
index 002181fc647a9e376dbda6384b43ac63c6f9c9f1..340bbb2db33eb9d7b75500adc69e5b68c6e8977c 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-cache.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-cache.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * BuddyPress Core Caching Functions.
+ *
  * Caching functions handle the clearing of cached objects and pages on specific
  * actions throughout BuddyPress.
  */
@@ -8,12 +10,12 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * REQUIRES WP-SUPER-CACHE
+ * Prune the WP Super Cache.
+ *
+ * @see prune_super_cache()
  *
  * When wp-super-cache is installed this function will clear cached pages
  * so that success/error messages are not cached, or time sensitive content.
- *
- * @package BuddyPress Core
  */
 function bp_core_clear_cache() {
 	global $cache_path;
@@ -25,9 +27,7 @@ function bp_core_clear_cache() {
 }
 
 /**
- * Add's 'bp' to global group of network wide cachable objects
- *
- * @package BuddyPress Core
+ * Add 'bp' to global group of network wide cachable objects.
  */
 function bp_core_add_global_group() {
 	if ( function_exists( 'wp_cache_add_global_groups' ) ) {
@@ -37,16 +37,14 @@ function bp_core_add_global_group() {
 add_action( 'bp_loaded', 'bp_core_add_global_group' );
 
 /**
- * Clears all cached objects for a user, or a user is part of.
- *
- * @package BuddyPress Core
+ * Clear all cached objects for a user, or those that a user is part of.
  */
 function bp_core_clear_user_object_cache( $user_id ) {
 	wp_cache_delete( 'bp_user_' . $user_id, 'bp' );
 }
 
 /**
- * Clears member count caches and transients
+ * Clear member count caches and transients.
  */
 function bp_core_clear_member_count_caches() {
 	wp_cache_delete( 'bp_total_member_count', 'bp' );
@@ -58,13 +56,122 @@ add_action( 'bp_core_deleted_account',        'bp_core_clear_member_count_caches
 add_action( 'bp_first_activity_for_member',   'bp_core_clear_member_count_caches' );
 add_action( 'deleted_user',                   'bp_core_clear_member_count_caches' );
 
+/**
+ * Clear the directory_pages cache when one of the pages is updated.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $post_id
+ */
+function bp_core_clear_directory_pages_cache_page_edit( $post_id ) {
+	if ( ! bp_is_root_blog() ) {
+		return;
+	}
+
+	// Bail if BP is not defined here
+	if ( ! buddypress() ) {
+		return;
+	}
+
+	$page_ids = bp_core_get_directory_page_ids();
+
+	if ( ! in_array( $post_id, (array) $page_ids ) ) {
+		return;
+	}
+
+	wp_cache_delete( 'directory_pages', 'bp' );
+}
+add_action( 'save_post', 'bp_core_clear_directory_pages_cache_page_edit' );
+
+/**
+ * Clear the directory_pages cache when the bp-pages option is updated.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $option Option name.
+ */
+function bp_core_clear_directory_pages_cache_settings_edit( $option ) {
+	if ( 'bp-pages' === $option ) {
+		wp_cache_delete( 'directory_pages', 'bp' );
+	}
+}
+add_action( 'update_option', 'bp_core_clear_directory_pages_cache_settings_edit' );
+
+/**
+ * Clear the root_blog_options cache when any of its options are updated.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $option Option name.
+ */
+function bp_core_clear_root_options_cache( $option ) {
+	$keys = array_keys( bp_get_default_options() );
+	$keys = array_merge( $keys, array(
+		'registration',
+		'avatar_default',
+		'tags_blog_id',
+		'sitewide_tags_blog',
+		'registration',
+		'fileupload_mask',
+	) );
+
+	if ( in_array( $option, $keys ) ) {
+		wp_cache_delete( 'root_blog_options', 'bp' );
+	}
+}
+add_action( 'update_option', 'bp_core_clear_root_options_cache' );
+add_action( 'update_site_option', 'bp_core_clear_root_options_cache' );
+add_action( 'add_option', 'bp_core_clear_root_options_cache' );
+add_action( 'add_site_option', 'bp_core_clear_root_options_cache' );
+
+/**
+ * Determine which items from a list do not have cached values.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $item_ids ID list.
+ * @param string $cache_group The cache group to check against.
+ * @return array
+ */
+function bp_get_non_cached_ids( $item_ids, $cache_group ) {
+	$uncached = array();
+
+	foreach ( $item_ids as $item_id ) {
+		$item_id = (int) $item_id;
+		if ( false === wp_cache_get( $item_id, $cache_group ) ) {
+			$uncached[] = $item_id;
+		}
+	}
+
+	return $uncached;
+}
+
 /**
  * Update the metadata cache for the specified objects.
  *
- * @since BuddyPress (1.6)
- * @global $wpdb WordPress database object for queries.
- * @param array $args See $defaults definition for more details
- * @return mixed Metadata cache for the specified objects, or false on failure.
+ * Based on WordPress's {@link update_meta_cache()}, this function primes the
+ * cache with metadata related to a set of objects. This is typically done when
+ * querying for a loop of objects; pre-fetching metadata for each queried
+ * object can lead to dramatic performance improvements when using metadata
+ * in the context of template loops.
+ *
+ * @since BuddyPress (1.6.0)
+ *
+ * @global $wpdb WordPress database object for queries..
+ *
+ * @param array $args {
+ *     Array of arguments.
+ *     @type array|string $object_ids List of object IDs to fetch metadata for.
+ *           Accepts an array or a comma-separated list of numeric IDs.
+ *     @type string $object_type The type of object, eg 'groups' or 'activity'.
+ *     @type string $meta_table The name of the metadata table being queried.
+ *     @type string $object_column Optional. The name of the database column
+ *           where IDs (those provided by $object_ids) are found. Eg, 'group_id'
+ *           for the groups metadata tables. Default: $object_type . '_id'.
+ *     @type string $cache_key_prefix Optional. The prefix to use when creating
+ *           cache key names. Default: the value of $meta_table.
+ * }
+ * @return array|bool Metadata cache for the specified objects, or false on failure.
  */
 function bp_update_meta_cache( $args = array() ) {
 	global $wpdb;
@@ -72,6 +179,7 @@ function bp_update_meta_cache( $args = array() ) {
 	$defaults = array(
 		'object_ids' 	   => array(), // Comma-separated list or array of item ids
 		'object_type' 	   => '',      // Canonical component id: groups, members, etc
+		'cache_group'      => '',      // Cache group
 		'meta_table' 	   => '',      // Name of the table containing the metadata
 		'object_column'    => '',      // DB column for the object ids (group_id, etc)
 		'cache_key_prefix' => ''       // Prefix to use when creating cache key names. Eg
@@ -80,7 +188,7 @@ function bp_update_meta_cache( $args = array() ) {
 	$r = wp_parse_args( $args, $defaults );
 	extract( $r );
 
-	if ( empty( $object_ids ) || empty( $object_type ) || empty( $meta_table ) ) {
+	if ( empty( $object_ids ) || empty( $object_type ) || empty( $meta_table ) || empty( $cache_group ) ) {
 		return false;
 	}
 
@@ -92,37 +200,44 @@ function bp_update_meta_cache( $args = array() ) {
 		$object_column = $object_type . '_id';
 	}
 
-	$object_ids = wp_parse_id_list( $object_ids );
+	if ( ! $cache_group ) {
+		return false;
+	}
+
+	$object_ids   = wp_parse_id_list( $object_ids );
+	$uncached_ids = bp_get_non_cached_ids( $object_ids, $cache_group );
 
 	$cache = array();
 
 	// Get meta info
-	$id_list   = join( ',', $object_ids );
-	$meta_list = $wpdb->get_results( $wpdb->prepare( "SELECT {$object_column}, meta_key, meta_value FROM {$meta_table} WHERE {$object_column} IN ($id_list)", $object_type ), ARRAY_A );
-
-	if ( !empty( $meta_list ) ) {
-		foreach ( $meta_list as $metarow ) {
-			$mpid = intval( $metarow[$object_column] );
-			$mkey = $metarow['meta_key'];
-			$mval = $metarow['meta_value'];
-
-			// Force subkeys to be array type:
-			if ( !isset( $cache[$mpid] ) || !is_array( $cache[$mpid] ) )
-				$cache[$mpid] = array();
-			if ( !isset( $cache[$mpid][$mkey] ) || !is_array( $cache[$mpid][$mkey] ) )
-				$cache[$mpid][$mkey] = array();
-
-			// Add a value to the current pid/key:
-			$cache[$mpid][$mkey][] = $mval;
+	if ( ! empty( $uncached_ids ) ) {
+		$id_list   = join( ',', wp_parse_id_list( $uncached_ids ) );
+		$meta_list = $wpdb->get_results( esc_sql( "SELECT {$object_column}, meta_key, meta_value FROM {$meta_table} WHERE {$object_column} IN ({$id_list})" ), ARRAY_A );
+
+		if ( ! empty( $meta_list ) ) {
+			foreach ( $meta_list as $metarow ) {
+				$mpid = intval( $metarow[$object_column] );
+				$mkey = $metarow['meta_key'];
+				$mval = $metarow['meta_value'];
+
+				// Force subkeys to be array type:
+				if ( !isset( $cache[$mpid] ) || !is_array( $cache[$mpid] ) )
+					$cache[$mpid] = array();
+				if ( !isset( $cache[$mpid][$mkey] ) || !is_array( $cache[$mpid][$mkey] ) )
+					$cache[$mpid][$mkey] = array();
+
+				// Add a value to the current pid/key:
+				$cache[$mpid][$mkey][] = $mval;
+			}
 		}
-	}
 
-	foreach ( $object_ids as $id ) {
-		if ( ! isset($cache[$id]) )
-			$cache[$id] = array();
+		foreach ( $uncached_ids as $uncached_id ) {
+			// Cache empty values as well
+			if ( ! isset( $cache[ $uncached_id ] ) ) {
+				$cache[ $uncached_id ] = array();
+			}
 
-		foreach( $cache[$id] as $meta_key => $meta_value ) {
-			wp_cache_set( $cache_key_prefix . '_' . $id . '_' . $meta_key, $meta_value, 'bp' );
+			wp_cache_set( $uncached_id, $cache[ $uncached_id ], $cache_group );
 		}
 	}
 
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-caps.php b/wp-content/plugins/buddypress/bp-core/bp-core-caps.php
index 4b5adee7636080ce8bf27d0fbb54b4efddfaa9a6..2ed693dd350b534c1a295dc2da9e06de7c860e77 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-caps.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-caps.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Capabilites
+ * BuddyPress Capabilites.
  *
  * @package BuddyPress
  * @subpackage Capabilities
@@ -11,15 +11,15 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Adds capabilities to WordPress user roles.
+ * Add capabilities to WordPress user roles.
  *
  * This is called on plugin activation.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @uses get_role() To get the administrator, default and moderator roles
- * @uses WP_Role::add_cap() To add various capabilities
- * @uses do_action() Calls 'bp_add_caps'
+ * @uses get_role() To get the administrator, default and moderator roles.
+ * @uses WP_Role::add_cap() To add various capabilities.
+ * @uses do_action() Calls 'bp_add_caps'.
  */
 function bp_add_caps() {
 	global $wp_roles;
@@ -39,15 +39,15 @@ function bp_add_caps() {
 }
 
 /**
- * Removes capabilities from WordPress user roles.
+ * Remove capabilities from WordPress user roles.
  *
  * This is called on plugin deactivation.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @uses get_role() To get the administrator and default roles
- * @uses WP_Role::remove_cap() To remove various capabilities
- * @uses do_action() Calls 'bp_remove_caps'
+ * @uses get_role() To get the administrator and default roles.
+ * @uses WP_Role::remove_cap() To remove various capabilities.
+ * @uses do_action() Calls 'bp_remove_caps'.
  */
 function bp_remove_caps() {
 	global $wp_roles;
@@ -67,31 +67,33 @@ function bp_remove_caps() {
 }
 
 /**
- * Maps community caps to built in WordPress caps
+ * Map community caps to built in WordPress caps.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param array $caps Capabilities for meta capability
- * @param string $cap Capability name
- * @param int $user_id User id
- * @param mixed $args Arguments
- * @uses get_post() To get the post
- * @uses get_post_type_object() To get the post type object
- * @uses apply_filters() Calls 'bp_map_meta_caps' with caps, cap, user id and
- *                        args
- * @return array Actual capabilities for meta capability
+ * @see WP_User::has_cap() for description of the arguments passed to the
+ *      'map_meta_cap' filter.
+ * @uses apply_filters() Calls 'bp_map_meta_caps' with caps, cap, user ID and
+ *       args.
+ *
+ * @param array $caps See {@link WP_User::has_cap()}.
+ * @param string $cap See {@link WP_User::has_cap()}.
+ * @param int $user_id See {@link WP_User::has_cap()}.
+ * @param mixed $args See {@link WP_User::has_cap()}.
+ * @return array Actual capabilities for meta capability. See {@link WP_User::has_cap()}.
  */
 function bp_map_meta_caps( $caps, $cap, $user_id, $args ) {
 	return apply_filters( 'bp_map_meta_caps', $caps, $cap, $user_id, $args );
 }
 
 /**
- * Return community capabilities
+ * Return community capabilities.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses apply_filters() Calls 'bp_get_community_caps' with the capabilities.
  *
- * @uses apply_filters() Calls 'bp_get_community_caps' with the capabilities
- * @return array Forum capabilities
+ * @return array Community capabilities.
  */
 function bp_get_community_caps() {
 
@@ -102,14 +104,14 @@ function bp_get_community_caps() {
 }
 
 /**
- * Returns an array of capabilities based on the role that is being requested.
+ * Return an array of capabilities based on the role that is being requested.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param string $role Optional. Defaults to The role to load caps for
- * @uses apply_filters() Allow return value to be filtered
+ * @uses apply_filters() Allow return value to be filtered.
  *
- * @return array Capabilities for $role
+ * @param string $role The role for which you're loading caps.
+ * @return array Capabilities for $role.
  */
 function bp_get_caps_for_role( $role = '' ) {
 
@@ -138,12 +140,14 @@ function bp_get_caps_for_role( $role = '' ) {
 }
 
 /**
- * Give a user the default 'Forum Participant' role when creating a topic/reply
- * on a site they do not have a role or capability on.
+ * Set a default role for the current user.
  *
- * @since BuddyPress (1.6)
+ * Give a user the default role when creating content on a site they do not
+ * already have a role or capability on.
+ *
+ * @since BuddyPress (1.6.0)
  *
- * @global BuddyPress $bp
+ * @global BuddyPress $bp Global BuddyPress settings object.
  *
  * @uses is_multisite()
  * @uses bp_allow_global_access()
@@ -171,14 +175,15 @@ function bp_set_current_user_default_role() {
 }
 
 /**
- * Whether current user has a capability or role. Can be passed blog ID, or will
- * use the root blod by default
+ * Check whether the current user has a given capability.
  *
- * @since BuddyPress (1.6)
+ * Can be passed blog ID, or will use the root blog by default.
+ *
+ * @since BuddyPress (1.6.0)
  *
  * @param string $capability Capability or role name.
- * @param int $blog_id Blog ID
- * @return bool
+ * @param int $blog_id Optional. Blog ID. Defaults to the BP root blog.
+ * @return bool True if the user has the cap for the given blog.
  */
 function bp_current_user_can( $capability, $blog_id = 0 ) {
 
@@ -192,27 +197,31 @@ function bp_current_user_can( $capability, $blog_id = 0 ) {
 }
 
 /**
- * Temporary implementation of 'bp_moderate' cap
+ * Temporary implementation of 'bp_moderate' cap.
  *
- * In BuddyPress 1.6, the 'bp_moderate' cap was introduced. In order to enforce that
- * bp_current_user_can( 'bp_moderate' ) always returns true for Administrators, we must manually
- * add the 'bp_moderate' cap to the list of user caps for Admins.
+ * In BuddyPress 1.6, the 'bp_moderate' cap was introduced. In order to
+ * enforce that bp_current_user_can( 'bp_moderate' ) always returns true for
+ * Administrators, we must manually add the 'bp_moderate' cap to the list of
+ * user caps for Admins.
  *
- * Note that this level of enforcement is only necessary in the case of non-Multisite. This is
- * because WordPress automatically assigns every capability - and thus 'bp_moderate' - to Super
- * Admins on a Multisite installation. See WP_User::has_cap().
+ * Note that this level of enforcement is only necessary in the case of
+ * non-Multisite. This is because WordPress automatically assigns every
+ * capability - and thus 'bp_moderate' - to Super Admins on a Multisite
+ * installation. See {@link WP_User::has_cap()}.
  *
- * This implementation of 'bp_moderate' is temporary, until BuddyPress properly matches caps to
- * roles and stores them in the database. Plugin authors: Do not use this function.
+ * This implementation of 'bp_moderate' is temporary, until BuddyPress properly
+ * matches caps to roles and stores them in the database. Plugin authors: Do
+ * not use this function.
  *
- * @since BuddyPress (1.6)
- * @see WP_User::has_cap()
  * @access private
+ * @since BuddyPress (1.6.0)
+ *
+ * @see WP_User::has_cap()
  *
- * @param array $allcaps The caps that WP associates with the given role
- * @param array $caps The caps being tested for in WP_User::has_cap()
- * @param array $args Miscellaneous arguments passed to the user_has_cap filter
- * @return array $allcaps The user's cap list, with 'bp_moderate' appended, if relevant
+ * @param array $allcaps The caps that WP associates with the given role.
+ * @param array $caps The caps being tested for in WP_User::has_cap().
+ * @param array $args Miscellaneous arguments passed to the user_has_cap filter.
+ * @return array $allcaps The user's cap list, with 'bp_moderate' appended, if relevant.
  */
 function _bp_enforce_bp_moderate_cap_for_admins( $caps = array(), $cap = '', $user_id = 0, $args = array() ) {
 
@@ -240,9 +249,8 @@ add_filter( 'map_meta_cap', '_bp_enforce_bp_moderate_cap_for_admins', 10, 4 );
  *
  * This is called on plugin activation.
  *
- * @since BuddyPress (1.6)
- *
- * @deprecated since version 1.7
+ * @since BuddyPress (1.6.0)
+ * @deprecated 1.7.0
  */
 function bp_add_roles() {
 	_doing_it_wrong( 'bp_add_roles', __( 'Special community roles no longer exist. Use mapped capabilities instead', 'buddypress' ), '1.7' );
@@ -253,9 +261,8 @@ function bp_add_roles() {
  *
  * This is called on plugin deactivation.
  *
- * @since BuddyPress (1.6)
- *
- * @deprecated since version 1.7
+ * @since BuddyPress (1.6.0)
+ * @deprecated 1.7.0
  */
 function bp_remove_roles() {
 	_doing_it_wrong( 'bp_remove_roles', __( 'Special community roles no longer exist. Use mapped capabilities instead', 'buddypress' ), '1.7' );
@@ -263,25 +270,23 @@ function bp_remove_roles() {
 
 
 /**
- * The participant role for registered users without roles
+ * The participant role for registered users without roles.
  *
  * This is primarily for multisite compatibility when users without roles on
- * sites that have global communities enabled
+ * sites that have global communities enabled.
  *
  * @since BuddyPress (1.6)
- *
- * @deprecated since version 1.7
+ * @deprecated 1.7.0
  */
 function bp_get_participant_role() {
 	_doing_it_wrong( 'bp_get_participant_role', __( 'Special community roles no longer exist. Use mapped capabilities instead', 'buddypress' ), '1.7' );
 }
 
 /**
- * The moderator role for BuddyPress users
- *
- * @since BuddyPress (1.6)
+ * The moderator role for BuddyPress users.
  *
- * @deprecated since version 1.7
+ * @since BuddyPress (1.6.0)
+ * @deprecated 1.7.0
  */
 function bp_get_moderator_role() {
 	_doing_it_wrong( 'bp_get_moderator_role', __( 'Special community roles no longer exist. Use mapped capabilities instead', 'buddypress' ), '1.7' );
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-catchuri.php b/wp-content/plugins/buddypress/bp-core/bp-core-catchuri.php
index 2fcb5641519ca5b4f6fc2f381d454e850c58ce3e..eaaa287c7ac37c05be27d4dbde68585aa14a02e4 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-catchuri.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-catchuri.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress URI catcher
+ * BuddyPress URI catcher.
  *
  * Functions for parsing the URI and determining which BuddyPress template file
  * to use on-screen.
@@ -14,12 +14,13 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Analyzes the URI structure and breaks it down into parts for use in code.
- * BuddyPress can use complete custom friendly URI's without the user having to
- * add new re-write rules. Custom components are able to use their own custom
+ * Analyze the URI and break it down into BuddyPress-usable chunks.
+ *
+ * BuddyPress can use complete custom friendly URIs without the user having to
+ * add new rewrite rules. Custom components are able to use their own custom
  * URI structures with very little work.
  *
- * The URI's are broken down as follows:
+ * The URIs are broken down as follows:
  *   - http:// domain.com / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ...
  *   - OUTSIDE ROOT: http:// domain.com / sites / buddypress / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ...
  *
@@ -29,8 +30,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
  *    - $bp->current_action: string 'edit'
  *    - $bp->action_variables: array ['group', 5]
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.0)
+ * @since BuddyPress (1.0.0)
  */
 function bp_core_set_uri_globals() {
 	global $bp, $current_blog, $wp_rewrite;
@@ -210,10 +210,6 @@ function bp_core_set_uri_globals() {
 			$matches[]  = 1;
 			$match      = $bp->pages->members;
 			$match->key = 'members';
-
-			// Without the 'members' URL chunk, WordPress won't know which page to load
-			// This filter intercepts the WP query and tells it to load the members page
-			add_filter( 'request', create_function( '$query_args', '$query_args["pagename"] = "' . $match->name . '"; return $query_args;' ) );
 		}
 	}
 
@@ -316,10 +312,11 @@ function bp_core_set_uri_globals() {
 }
 
 /**
- * Are root profiles enabled and allowed
+ * Are root profiles enabled and allowed?
+ *
+ * @since BuddyPress (1.6.0)
  *
- * @since BuddyPress (1.6)
- * @return bool True if yes, false if no
+ * @return bool True if yes, false if no.
  */
 function bp_core_enable_root_profiles() {
 
@@ -339,9 +336,8 @@ function bp_core_enable_root_profiles() {
  * Loads:
  *   wp-content/themes/[activated_theme]/members/index.php
  *
- * @package BuddyPress Core
- * @param string $username Username to check.
- * @return int|bool The user ID of the matched user, or false.
+ * @param array $templates Array of templates to attempt to load.
+ * @return bool|null Returns false on failure.
  */
 function bp_core_load_template( $templates ) {
 	global $post, $bp, $wp_query, $wpdb;
@@ -364,7 +360,7 @@ function bp_core_load_template( $templates ) {
 
 	// Make the queried/post object an actual valid page
 	if ( !empty( $object_id ) ) {
-		$wp_query->queried_object    = &get_post( $object_id );
+		$wp_query->queried_object    = get_post( $object_id );
 		$wp_query->queried_object_id = $object_id;
 		$post                        = $wp_query->queried_object;
 	}
@@ -383,7 +379,7 @@ function bp_core_load_template( $templates ) {
 		status_header( 200 );
 		$wp_query->is_page     = true;
 		$wp_query->is_singular = true;
-		$wp_query->is_404      = false;			
+		$wp_query->is_404      = false;
 
 		do_action( 'bp_core_pre_load_template', $located_template );
 
@@ -404,7 +400,7 @@ function bp_core_load_template( $templates ) {
 			status_header( 200 );
 			$wp_query->is_page     = true;
 			$wp_query->is_singular = true;
-			$wp_query->is_404      = false;			
+			$wp_query->is_404      = false;
 		}
 
 		do_action( 'bp_setup_theme_compat' );
@@ -412,11 +408,7 @@ function bp_core_load_template( $templates ) {
 }
 
 /**
- * bp_core_catch_profile_uri()
- *
- * If the extended profiles component is not installed we still need
- * to catch the /profile URI's and display whatever we have installed.
- *
+ * Redirect away from /profile URIs if XProfile is not enabled.
  */
 function bp_core_catch_profile_uri() {
 	if ( !bp_is_active( 'xprofile' ) ) {
@@ -425,10 +417,9 @@ function bp_core_catch_profile_uri() {
 }
 
 /**
- * Catches invalid access to BuddyPress pages and redirects them accordingly.
+ * Catch unauthorized access to certain BuddyPress pages and redirect accordingly.
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  */
 function bp_core_catch_no_access() {
 	global $bp, $wp_query;
@@ -445,12 +436,26 @@ function bp_core_catch_no_access() {
 add_action( 'bp_template_redirect', 'bp_core_catch_no_access', 1 );
 
 /**
- * Redirects a user to login for BP pages that require access control and adds an error message (if
- * one is provided).
+ * Redirect a user to log in for BP pages that require access control.
+ *
+ * Add an error message (if one is provided).
+ *
  * If authenticated, redirects user back to requested content by default.
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @param array $args {
+ *     @type int $mode Specifies the destintation of the redirect. 1 will
+ *           direct to the root domain (home page), which assumes you have a
+ *           log-in form there; 2 directs to wp-login.php. Default: 2.
+ *     @type string $redirect The URL the user will be redirected to after
+ *           successfully logging in. Default: the URL originally requested.
+ *     @type string $root The root URL of the site, used in case of error or
+ *           mode 1 redirects. Default: the value of {@link bp_get_root_domain()}.
+ *     @type string $message An error message to display to the user on the
+ *           log-in page. Default: "You must log in to access the page you
+ *           requested."
+ * }
  */
 function bp_core_no_access( $args = '' ) {
 
@@ -512,12 +517,13 @@ function bp_core_no_access( $args = '' ) {
 }
 
 /**
- * Adds an error message to wp-login.php.
+ * Add an error message to wp-login.php.
+ *
  * Hooks into the "bpnoaccess" action defined in bp_core_no_access().
  *
- * @package BuddyPress Core
- * @global $error
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @global $error Error message to pass to wp-login.php
  */
 function bp_core_no_access_wp_login_error() {
 	global $error;
@@ -530,17 +536,19 @@ function bp_core_no_access_wp_login_error() {
 add_action( 'login_form_bpnoaccess', 'bp_core_no_access_wp_login_error' );
 
 /**
- * Canonicalizes BuddyPress URLs
+ * Canonicalize BuddyPress URLs.
  *
- * This function ensures that requests for BuddyPress content are always redirected to their
- * canonical versions. Canonical versions are always trailingslashed, and are typically the most
- * general possible versions of the URL - eg, example.com/groups/mygroup/ instead of
- * example.com/groups/mygroup/home/
+ * This function ensures that requests for BuddyPress content are always
+ * redirected to their canonical versions. Canonical versions are always
+ * trailingslashed, and are typically the most general possible versions of the
+ * URL - eg, example.com/groups/mygroup/ instead of
+ * example.com/groups/mygroup/home/.
  *
- * @since BuddyPress (1.6)
- * @see BP_Members_Component::setup_globals() where $bp->canonical_stack['base_url'] and
- *   ['component'] may be set
- * @see bp_core_new_nav_item() where $bp->canonical_stack['action'] may be set
+ * @since BuddyPress (1.6.0)
+ *
+ * @see BP_Members_Component::setup_globals() where
+ *      $bp->canonical_stack['base_url'] and ['component'] may be set.
+ * @see bp_core_new_nav_item() where $bp->canonical_stack['action'] may be set.
  * @uses bp_get_canonical_url()
  * @uses bp_get_requested_url()
  */
@@ -588,9 +596,9 @@ function bp_redirect_canonical() {
 }
 
 /**
- * Output rel=canonical header tag for BuddyPress content
+ * Output rel=canonical header tag for BuddyPress content.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 function bp_rel_canonical() {
 	$canonical_url = bp_get_canonical_url();
@@ -600,12 +608,18 @@ function bp_rel_canonical() {
 }
 
 /**
- * Returns the canonical URL of the current page
+ * Get the canonical URL of the current page.
+ *
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses apply_filters() Filter bp_get_canonical_url to modify return value.
  *
- * @since BuddyPress (1.6)
- * @uses apply_filters() Filter bp_get_canonical_url to modify return value
- * @param array $args
- * @return string
+ * @param array $args {
+ *     Optional array of arguments.
+ *     @type bool $include_query_args Whether to include current URL arguments
+ *           in the canonical URL returned from the function.
+ * }
+ * @return string Canonical URL for the current page.
  */
 function bp_get_canonical_url( $args = array() ) {
 	global $bp;
@@ -621,6 +635,27 @@ function bp_get_canonical_url( $args = array() ) {
 	$r = wp_parse_args( $args, $defaults );
 	extract( $r );
 
+	// Special case: when a BuddyPress directory (eg example.com/members)
+	// is set to be the front page, ensure that the current canonical URL
+	// is the home page URL.
+	if ( 'page' == get_option( 'show_on_front' ) && $page_on_front = (int) get_option( 'page_on_front' ) ) {
+		$front_page_component = array_search( $page_on_front, bp_core_get_directory_page_ids() );
+
+		// If requesting the front page component directory, canonical
+		// URL is the front page. We detect whether we're detecting a
+		// component *directory* by checking that bp_current_action()
+		// is empty - ie, this not a single item or a feed
+		if ( false !== $front_page_component && bp_is_current_component( $front_page_component ) && ! bp_current_action() ) {
+			$bp->canonical_stack['canonical_url'] = trailingslashit( bp_get_root_domain() );
+
+		// Except when the front page is set to the registration page
+		// and the current user is logged in. In this case we send to
+		// the members directory to avoid redirect loops
+		} else if ( bp_is_register_page() && 'register' == $front_page_component && is_user_logged_in() ) {
+			$bp->canonical_stack['canonical_url'] = apply_filters( 'bp_loggedin_register_page_redirect_to', trailingslashit( bp_get_root_domain() . '/' . bp_get_members_root_slug() ) );
+		}
+	}
+
 	if ( empty( $bp->canonical_stack['canonical_url'] ) ) {
 		// Build the URL in the address bar
 		$requested_url  = bp_get_requested_url();
@@ -654,17 +689,19 @@ function bp_get_canonical_url( $args = array() ) {
 	$canonical_url = $bp->canonical_stack['canonical_url'];
 
 	if ( !$include_query_args ) {
-		$canonical_url = array_pop( array_reverse( explode( '?', $canonical_url ) ) );
+		$canonical_url = array_reverse( explode( '?', $canonical_url ) );
+		$canonical_url = array_pop( $canonical_url );
 	}
 
 	return apply_filters( 'bp_get_canonical_url', $canonical_url, $args );
 }
 
 /**
- * Returns the URL as requested on the current page load by the user agent
+ * Return the URL as requested on the current page load by the user agent.
+ *
+ * @since BuddyPress (1.6.0)
  *
- * @since BuddyPress (1.6)
- * @return string
+ * @return string Requested URL string.
  */
 function bp_get_requested_url() {
 	global $bp;
@@ -678,14 +715,16 @@ function bp_get_requested_url() {
 }
 
 /**
- * Remove WordPress's really awesome canonical redirect if we are trying to load
- * BuddyPress specific content. Avoids issues with WordPress thinking that a
- * BuddyPress URL might actually be a blog post or page.
+ * Remove WP's canonical redirect when we are trying to load BP-specific content.
+ *
+ * Avoids issues with WordPress thinking that a BuddyPress URL might actually
+ * be a blog post or page.
  *
  * This function should be considered temporary, and may be removed without
  * notice in future versions of BuddyPress.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
  * @uses bp_is_blog_page()
  */
 function _bp_maybe_remove_redirect_canonical() {
@@ -695,7 +734,7 @@ function _bp_maybe_remove_redirect_canonical() {
 add_action( 'bp_init', '_bp_maybe_remove_redirect_canonical' );
 
 /**
- * Rehook maybe_redirect_404() to run later than the default
+ * Rehook maybe_redirect_404() to run later than the default.
  *
  * WordPress's maybe_redirect_404() allows admins on a multisite installation
  * to define 'NOBLOGREDIRECT', a URL to which 404 requests will be redirected.
@@ -730,13 +769,12 @@ function _bp_rehook_maybe_redirect_404() {
 add_action( 'template_redirect', '_bp_rehook_maybe_redirect_404', 1 );
 
 /**
- * Remove WordPress's rel=canonical HTML tag if we are trying to load BuddyPress
- * specific content.
+ * Remove WP's rel=canonical HTML tag if we are trying to load BP-specific content.
  *
  * This function should be considered temporary, and may be removed without
  * notice in future versions of BuddyPress.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 function _bp_maybe_remove_rel_canonical() {
 	if ( ! bp_is_blog_page() && ! is_404() ) {
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-classes.php b/wp-content/plugins/buddypress/bp-core/bp-core-classes.php
index 36b57ed1f4fdce7da21674226d6c1c7289e21816..d1f2a23a3d61bed6964783521e515c424cf52f42 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-classes.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-classes.php
@@ -1,108 +1,120 @@
 <?php
+/**
+ * Core component classes.
+ *
+ * @package BuddyPress
+ * @subpackage Core
+ */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * BuddyPress User Query class
+ * BuddyPress User Query class.
  *
  * Used for querying users in a BuddyPress context, in situations where
  * WP_User_Query won't do the trick: Member directories, the Friends component,
  * etc.
  *
- * Accepted parameters:
- *   type	     - Determines sort order. Select from 'newest', 'active',
- *                     'online', 'random', 'popular', 'alphabetical'
- *   per_page        - Number of results to return
- *   page            - Page offset (together with per_page)
- *   user_id         - Pass a single numeric user id to limit results to
- *                     friends of that user. Requires the Friends component
- *   search_terms    - Terms to search by. Search happens across xprofile
- *                     fields. Requires XProfile component
- *   include         - An array or comma-separated list of user ids. Results
- *                     will be limited to users in this list
- *   exclude         - An array or comma-separated list of user ids. Results
- *                     will not include any users in this list
- *   user_ids        - An array or comma-separated list of user ids. When
- *                     this parameter is passed, it will override all other
- *                     parameters; BP User objects will be constructed using
- *                     these IDs only
- *   meta_key        - Limit results to users that have usermeta associated
- *                     with this meta_key. Usually used with meta_value
- *   meta_value      - When used with meta_key, limits results to users whose
- *                     usermeta value associated with meta_key matches
- *                     meta_value
- *   populate_extras - Boolean. True if you want to fetch extra metadata about
- *                     returned users, such as total group and friend counts
- *   count_total     - Determines how BP_User_Query will do a count of total
- *                     users matching the other filter criteria. Default value
- *                     is 'count_query', which does a separate SELECT COUNT
- *                     query to determine the total. 'sql_count_found_rows'
- *                     uses SQL_COUNT_FOUND_ROWS and SELECT FOUND_ROWS(). Pass
- *                     an empty string to skip the total user count query.
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
+ * @param array $query {
+ *     Query arguments. All items are optional.
+ *     @type string $type Determines sort order. Select from 'newest', 'active',
+ *           'online', 'random', 'popular', 'alphabetical'. Default: 'newest'.
+ *     @type int $per_page Number of results to return. Default: 0 (no limit).
+ *     @type int $page Page offset (together with $per_page). Default: 1.
+ *     @type int $user_id ID of a user. If present, and if the friends
+ *           component is activated, results will be limited to the friends of
+ *           that user. Default: 0.
+ *     @type string|bool $search_terms Terms to search by. Search happens
+ *           across xprofile fields. Requires XProfile component.
+ *           Default: false.
+ *     @type array|string|bool $include An array or comma-separated list of
+ *           user IDs to which query should be limited.
+ *           Default: false.
+ *     @type array|string|bool $exclude An array or comma-separated list of
+ *           user IDs that will be excluded from query results. Default: false.
+ *     @type array|string|bool $user_ids An array or comma-separated list of
+ *           IDs corresponding to the users that should be returned. When this
+ *           parameter is passed, it will override all others; BP User objects
+ *           will be constructed using these IDs only. Default: false.
+ *     @type string|bool $meta_key Limit results to users that have usermeta
+ *           associated with this meta_key. Usually used with $meta_value.
+ *           Default: false.
+ *     @type string|bool $meta_value When used with $meta_key, limits results
+ *           to users whose usermeta value associated with $meta_key matches
+ *           $meta_value. Default: false.
+ *     @type bool $populate_extras True if you want to fetch extra metadata
+ *           about returned users, such as total group and friend counts.
+ *     @type string $count_total Determines how BP_User_Query will do a count
+ *           of total users matching the other filter criteria. Default value
+ *           is 'count_query', which does a separate SELECT COUNT query to
+ *           determine the total. 'sql_count_found_rows' uses
+ *           SQL_COUNT_FOUND_ROWS and SELECT FOUND_ROWS(). Pass an empty string
+ *           to skip the total user count query.
+ * }
  */
 class BP_User_Query {
 
 	/** Variables *************************************************************/
 
 	/**
-	 * Unaltered params as passed to the constructor
+	 * Unaltered params as passed to the constructor.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 * @var array
 	 */
 	public $query_vars_raw = array();
 
 	/**
-	 * Array of variables to query with
+	 * Array of variables to query with.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 * @var array
 	 */
 	public $query_vars = array();
 
 	/**
-	 * List of found users and their respective data
+	 * List of found users and their respective data.
 	 *
-	 * @since BuddyPress (1.7)
-	 * @access public To allow components to manipulate them
+	 * @access public To allow components to manipulate them.
+	 * @since BuddyPress (1.7.0)
 	 * @var array
 	 */
 	public $results = array();
 
 	/**
-	 * Total number of found users for the current query
+	 * Total number of found users for the current query.
 	 *
-	 * @since BuddyPress (1.7)
-	 * @access public To allow components to manipulate it
+	 * @access public To allow components to manipulate it.
+	 * @since BuddyPress (1.7.0)
 	 * @var int
 	 */
 	public $total_users = 0;
 
 	/**
-	 * List of found user ID's
+	 * List of found user IDs.
 	 *
-	 * @since BuddyPress (1.7)
-	 * @access public To allow components to manipulate it
+	 * @access public To allow components to manipulate it.
+	 * @since BuddyPress (1.7.0)
 	 * @var array
 	 */
 	public $user_ids = array();
 
 	/**
-	 * SQL clauses for the user ID query
+	 * SQL clauses for the user ID query.
 	 *
-	 * @since BuddyPress (1.7)
-	 * @access public To allow components to manipulate it
-	 * @var array()
+	 * @access public To allow components to manipulate it.
+	 * @since BuddyPress (1.7.0)
+	 * @var array
 	 */
 	public $uid_clauses = array();
 
 	/**
-	 * SQL database column name to order by
+	 * SQL database column name to order by.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 * @var string
 	 */
 	public $uid_name = '';
@@ -110,8 +122,8 @@ class BP_User_Query {
 	/**
 	 * Standard response when the query should not return any rows.
 	 *
-	 * @since BuddyPress (1.7)
 	 * @access protected
+	 * @since BuddyPress (1.7.0)
 	 * @var string
 	 */
 	protected $no_results = array( 'join' => '', 'where' => '0 = 1' );
@@ -120,11 +132,11 @@ class BP_User_Query {
 	/** Methods ***************************************************************/
 
 	/**
-	 * Constructor
+	 * Constructor.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @param string|array $query The query variables
+	 * @param string|array $query See {@link BP_User_Query}.
 	 */
 	public function __construct( $query = null ) {
 
@@ -177,7 +189,7 @@ class BP_User_Query {
 	}
 
 	/**
-	 * Allow extending classes to set up action/filter hooks
+	 * Allow extending classes to set up action/filter hooks.
 	 *
 	 * When extending BP_User_Query, you may need to use some of its
 	 * internal hooks to modify the output. It's not convenient to call
@@ -186,16 +198,16 @@ class BP_User_Query {
 	 * you may not want to override in your class. Define this method in
 	 * your own class if you need a place where your extending class can
 	 * add its hooks early in the query-building process. See
-	 * BP_Group_Member_Query::setup_hooks() for an example.
+	 * {@link BP_Group_Member_Query::setup_hooks()} for an example.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public function setup_hooks() {}
 
 	/**
-	 * Prepare the query for user_ids
+	 * Prepare the query for user_ids.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function prepare_user_ids_query() {
 		global $wpdb, $bp;
@@ -233,10 +245,10 @@ class BP_User_Query {
 			// number of minutes used as an interval
 			case 'online' :
 				$this->uid_name = 'user_id';
-				$sql['select']  = "SELECT DISTINCT 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;
@@ -247,8 +259,8 @@ class BP_User_Query {
 			case 'newest' :
 			case 'random' :
 				$this->uid_name = 'user_id';
-				$sql['select']  = "SELECT DISTINCT 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";
@@ -256,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";
 				}
 
@@ -265,7 +277,7 @@ class BP_User_Query {
 			// 'popular' sorts by the 'total_friend_count' usermeta
 			case 'popular' :
 				$this->uid_name = 'user_id';
-				$sql['select']  = "SELECT DISTINCT u.{$this->uid_name} as id FROM {$wpdb->usermeta} u";
+				$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( 'total_friend_count' ) );
 				$sql['orderby'] = "ORDER BY CONVERT(u.meta_value, SIGNED)";
 				$sql['order']   = "DESC";
@@ -282,28 +294,31 @@ class BP_User_Query {
 				// @todo remove need for bp_is_active() check
 				if ( ! bp_disable_profile_sync() || ! bp_is_active( 'xprofile' ) ) {
 					$this->uid_name = 'ID';
-					$sql['select']  = "SELECT DISTINCT u.{$this->uid_name} as id FROM {$wpdb->users} u";
+					$sql['select']  = "SELECT u.{$this->uid_name} as id FROM {$wpdb->users} u";
 					$sql['orderby'] = "ORDER BY u.display_name";
 					$sql['order']   = "ASC";
 
 				// When profile sync is disabled, alphabetical sorts must happen against
 				// the xprofile table
 				} else {
-					$fullname_field_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", bp_xprofile_fullname_field_name() ) );
-
 					$this->uid_name = 'user_id';
-					$sql['select']  = "SELECT DISTINCT u.{$this->uid_name} as id FROM {$bp->profile->table_name_data} u";
-					$sql['where'][] = "u.field_id = {$fullname_field_id}";
+					$sql['select']  = "SELECT u.{$this->uid_name} as id FROM {$bp->profile->table_name_data} u";
+					$sql['where'][] = $wpdb->prepare( "u.field_id = %d", bp_xprofile_fullname_field_id() );
 					$sql['orderby'] = "ORDER BY u.value";
 					$sql['order']   = "ASC";
 				}
 
+				// Alphabetical queries ignore last_activity, while BP uses last_activity
+				// to infer spam/deleted/non-activated users. To ensure that these users
+				// are filtered out, we add an appropriate sub-query.
+				$sql['where'][] = "u.{$this->uid_name} IN ( SELECT ID FROM {$wpdb->users} WHERE " . bp_core_get_status_sql( '' ) . " )";
+
 				break;
 
 			// Any other 'type' falls through
 			default :
 				$this->uid_name = 'ID';
-				$sql['select']  = "SELECT DISTINCT u.{$this->uid_name} as id FROM {$wpdb->users} u";
+				$sql['select']  = "SELECT u.{$this->uid_name} as id FROM {$wpdb->users} u";
 
 				// In this case, we assume that a plugin is
 				// handling order, so we leave those clauses
@@ -346,20 +361,11 @@ class BP_User_Query {
 
 		/** Search Terms ******************************************************/
 
-		// 'search_terms' searches the xprofile fields
-		// To avoid global joins, do a separate query
-		// @todo remove need for bp_is_active() check
-		if ( false !== $search_terms && bp_is_active( 'xprofile' ) ) {
-			$search_terms_clean = mysql_real_escape_string( mysql_real_escape_string( $search_terms ) );
-			$search_terms_clean = like_escape( $search_terms_clean );
-			$found_user_ids_query = "SELECT user_id FROM {$bp->profile->table_name_data} WHERE value LIKE '%" . $search_terms_clean . "%'";
-			$found_user_ids = $wpdb->get_col( $found_user_ids_query );
-
-			if ( ! empty( $found_user_ids ) ) {
-				$sql['where'][] = "u.{$this->uid_name} IN (" . implode( ',', wp_parse_id_list( $found_user_ids ) ) . ")";
-			} else {
-				$sql['where'][] = $this->no_results['where'];
-			}
+		// 'search_terms' searches user_login and user_nicename
+		// xprofile field matches happen in bp_xprofile_bp_user_query_search()
+		if ( false !== $search_terms ) {
+			$search_terms_clean = esc_sql( esc_sql( $search_terms ) );
+			$sql['where']['search'] = "u.{$this->uid_name} IN ( SELECT ID FROM {$wpdb->users} WHERE ( user_login LIKE '%{$search_terms_clean}%' OR user_nicename LIKE '%{$search_terms_clean}%' ) )";
 		}
 
 		// 'meta_key', 'meta_value' allow usermeta search
@@ -385,6 +391,9 @@ class BP_User_Query {
 			$sql['limit'] = '';
 		}
 
+		// Allow custom filters
+		$sql = apply_filters_ref_array( 'bp_user_query_uid_clauses', array( $sql, &$this ) );
+
 		// Assemble the query chunks
 		$this->uid_clauses['select']  = $sql['select'];
 		$this->uid_clauses['where']   = ! empty( $sql['where'] ) ? 'WHERE ' . implode( ' AND ', $sql['where'] ) : '';
@@ -396,12 +405,14 @@ class BP_User_Query {
 	}
 
 	/**
+	 * Query for IDs of users that match the query parameters.
+	 *
 	 * Perform a database query to specifically get only user IDs, using
 	 * existing query variables set previously in the constructor.
 	 *
 	 * Also used to quickly perform user total counts.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function do_user_ids_query() {
 		global $wpdb;
@@ -418,22 +429,28 @@ class BP_User_Query {
 		if ( 'sql_calc_found_rows' == $this->query_vars['count_total'] ) {
 			$this->total_users = $wpdb->get_var( apply_filters( 'bp_found_user_query', "SELECT FOUND_ROWS()", $this ) );
 		} elseif ( 'count_query' == $this->query_vars['count_total'] ) {
-			$count_select      = preg_replace( '/^SELECT.*?FROM (\S+) u/', "SELECT COUNT(DISTINCT u.{$this->uid_name}) FROM $1 u", $this->uid_clauses['select'] );
+			$count_select      = preg_replace( '/^SELECT.*?FROM (\S+) u/', "SELECT COUNT(u.{$this->uid_name}) FROM $1 u", $this->uid_clauses['select'] );
 			$this->total_users = $wpdb->get_var( apply_filters( 'bp_found_user_query', "{$count_select} {$this->uid_clauses['where']}", $this ) );
 		}
 	}
 
 	/**
-	 * Perform a database query using the WP_User_Query() object, using existing
-	 * fields, variables, and user ID's set previously in this class.
+	 * Use WP_User_Query() to pull data for the user IDs retrieved in the main query.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function do_wp_user_query() {
+		$fields = array( 'ID', 'user_login', 'user_pass', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'user_activation_key', 'user_status', 'display_name' );
+
+		if ( is_multisite() ) {
+			$fields[] = 'spam';
+			$fields[] = 'deleted';
+		}
+
 		$wp_user_query = new WP_User_Query( apply_filters( 'bp_wp_user_query_args', array(
 
 			// Relevant
-			'fields'      => array( 'ID', 'user_registered', 'user_login', 'user_nicename', 'display_name', 'user_email' ),
+			'fields'      => $fields,
 			'include'     => $this->user_ids,
 
 			// Overrides
@@ -442,6 +459,22 @@ class BP_User_Query {
 
 		), $this ) );
 
+		// WP_User_Query doesn't cache the data it pulls from wp_users,
+		// and it does not give us a way to save queries by fetching
+		// only uncached users. However, BP does cache this data, so
+		// we set it here.
+		foreach ( $wp_user_query->results as $u ) {
+			wp_cache_set( 'bp_core_userdata_' . $u->ID, $u, 'bp' );
+		}
+
+		// We calculate total_users using a standalone query, except
+		// when a whitelist of user_ids is passed to the constructor.
+		// This clause covers the latter situation, and ensures that
+		// pagination works when querying by $user_ids.
+		if ( empty( $this->total_users ) ) {
+			$this->total_users = count( $wp_user_query->results );
+		}
+
 		// Reindex for easier matching
 		$r = array();
 		foreach ( $wp_user_query->results as $u ) {
@@ -461,20 +494,21 @@ class BP_User_Query {
 	}
 
 	/**
-	 * Fetches the ids of users to put in the IN clause of the main query
+	 * Fetch the IDs of users to put in the IN clause of the main query.
 	 *
 	 * By default, returns the value passed to it
 	 * ($this->query_vars['include']). Having this abstracted into a
 	 * standalone method means that extending classes can override the
 	 * logic, parsing together their own user_id limits with the 'include'
-	 * ids passed to the class constructor. See BP_Group_Member_Query for
-	 * an example.
+	 * ids passed to the class constructor. See {@link BP_Group_Member_Query}
+	 * for an example.
+	 *
+	 * @since BuddyPress (1.8.0)
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param array Sanitized array of user ids, as passed to the 'include'
-	 *   parameter of the class constructor
+	 * @param array Sanitized array of user IDs, as passed to the 'include'
+	 *        parameter of the class constructor.
 	 * @return array The list of users to which the main query should be
-	 *   limited
+	 *         limited.
 	 */
 	public function get_include_ids( $include = array() ) {
 		return $include;
@@ -482,14 +516,14 @@ class BP_User_Query {
 
 	/**
 	 * Perform a database query to populate any extra metadata we might need.
+	 *
 	 * Different components will hook into the 'bp_user_query_populate_extras'
 	 * action to loop in the things they want.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @global BuddyPress $bp
-	 * @global WPDB $wpdb
-	 * @return
+	 * @global BuddyPress $bp Global BuddyPress settings object.
+	 * @global WPDB $wpdb Global WordPress database access object.
 	 */
 	public function populate_extras() {
 		global $wpdb;
@@ -513,6 +547,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.
 		 *
@@ -528,13 +564,20 @@ 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 );
+
+		// Set a last_activity value for each user, even if it's empty
+		foreach ( $this->results as $user_id => $user ) {
+			$user_last_activity = isset( $last_activities[ $user_id ] ) ? $last_activities[ $user_id ]['date_recorded'] : '';
+			$this->results[ $user_id ]->last_activity = $user_last_activity;
+		}
+
 		// 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
@@ -544,7 +587,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.
@@ -554,10 +597,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;
@@ -599,6 +638,8 @@ class BP_User_Query {
 }
 
 /**
+ * Fetch data about a BuddyPress user.
+ *
  * BP_Core_User class can be used by any component. It will fetch useful
  * details for any user when provided with a user_id.
  *
@@ -608,8 +649,6 @@ class BP_User_Query {
  *	  $user_email = $user->email;
  *    $user_status = $user->status;
  *    etc.
- *
- * @package BuddyPress Core
  */
 class BP_Core_User {
 
@@ -618,56 +657,56 @@ class BP_Core_User {
 	 *
 	 * @var integer
 	 */
-	var $id;
+	public $id;
 
 	/**
 	 * The URL to the full size of the avatar for the user.
 	 *
 	 * @var string
 	 */
-	var $avatar;
+	public $avatar;
 
 	/**
 	 * The URL to the thumb size of the avatar for the user.
 	 *
 	 * @var string
 	 */
-	var $avatar_thumb;
+	public $avatar_thumb;
 
 	/**
 	 * The URL to the mini size of the avatar for the user.
 	 *
 	 * @var string
 	 */
-	var $avatar_mini;
+	public $avatar_mini;
 
 	/**
 	 * The full name of the user
 	 *
 	 * @var string
 	 */
-	var $fullname;
+	public $fullname;
 
 	/**
 	 * The email for the user.
 	 *
 	 * @var string
 	 */
-	var $email;
+	public $email;
 
 	/**
 	 * The absolute url for the user's profile.
 	 *
 	 * @var string
 	 */
-	var $user_url;
+	public $user_url;
 
 	/**
 	 * The HTML for the user link, with the link text being the user's full name.
 	 *
 	 * @var string
 	 */
-	var $user_link;
+	public $user_link;
 
 	/**
 	 * Contains a formatted string when the last time the user was active.
@@ -676,7 +715,7 @@ class BP_Core_User {
 	 *
 	 * @var string
 	 */
-	var $last_active;
+	public $last_active;
 
 	/* Extras */
 
@@ -685,7 +724,7 @@ class BP_Core_User {
 	 *
 	 * @var integer
 	 */
-	var $total_friends;
+	public $total_friends;
 
 	/**
 	 * The total number of blog posts posted by the user
@@ -693,7 +732,7 @@ class BP_Core_User {
 	 * @var integer
 	 * @deprecated No longer used
 	 */
-	var $total_blogs;
+	public $total_blogs;
 
 	/**
 	 * The total number of groups the user is a part of.
@@ -702,12 +741,12 @@ class BP_Core_User {
 	 *
 	 * @var string
 	 */
-	var $total_groups;
+	public $total_groups;
 
 	/**
 	 * Profile information for the specific user.
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var array
 	 */
 	public $profile_data;
@@ -717,10 +756,11 @@ class BP_Core_User {
 	/**
 	 * Class constructor.
 	 *
-	 * @param integer $user_id The ID for the user
-	 * @param boolean $populate_extras Whether to fetch extra information such as group/friendship counts or not.
+	 * @param integer $user_id The ID for the user being queried.
+	 * @param bool $populate_extras Whether to fetch extra information
+	 *        such as group/friendship counts or not. Default: false.
 	 */
-	function __construct( $user_id, $populate_extras = false ) {
+	public function __construct( $user_id, $populate_extras = false ) {
 		if ( !empty( $user_id ) ) {
 			$this->id = $user_id;
 			$this->populate();
@@ -731,19 +771,22 @@ class BP_Core_User {
 		}
 	}
 
-	/** Private Methods *******************************************************/
-
 	/**
 	 * Populate the instantiated class with data based on the User ID provided.
 	 *
-	 * @uses bp_core_get_userurl() Returns the URL with no HTML markup for a user based on their user id
-	 * @uses bp_core_get_userlink() Returns a HTML formatted link for a user with the user's full name as the link text
-	 * @uses bp_core_get_user_email() Returns the email address for the user based on user ID
-	 * @uses bp_get_user_meta() BP function returns the value of passed usermeta name from usermeta table
+	 * @uses bp_core_get_userurl() Returns the URL with no HTML markup for
+	 *       a user based on their user id.
+	 * @uses bp_core_get_userlink() Returns a HTML formatted link for a
+	 *       user with the user's full name as the link text.
+	 * @uses bp_core_get_user_email() Returns the email address for the
+	 *       user based on user ID.
+	 * @uses bp_get_user_meta() BP function returns the value of passed
+	 *       usermeta name from usermeta table.
 	 * @uses bp_core_fetch_avatar() Returns HTML formatted avatar for a user
-	 * @uses bp_profile_last_updated_date() Returns the last updated date for a user.
+	 * @uses bp_profile_last_updated_date() Returns the last updated date
+	 *       for a user.
 	 */
-	function populate() {
+	public function populate() {
 
 		if ( bp_is_active( 'xprofile' ) )
 			$this->profile_data = $this->get_profile_data();
@@ -770,13 +813,13 @@ class BP_Core_User {
 		$this->avatar       = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'full', 'alt' => sprintf( __( 'Avatar of %s', 'buddypress' ), $this->fullname ) ) );
 		$this->avatar_thumb = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'thumb', 'alt' => sprintf( __( 'Avatar of %s', 'buddypress' ), $this->fullname ) ) );
 		$this->avatar_mini  = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'thumb', 'alt' => sprintf( __( 'Avatar of %s', 'buddypress' ), $this->fullname ), 'width' => 30, 'height' => 30 ) );
-		$this->last_active  = bp_core_get_last_activity( bp_get_user_meta( $this->id, 'last_activity', true ), __( 'active %s', 'buddypress' ) );
+		$this->last_active  = bp_core_get_last_activity( bp_get_user_last_activity( $this->id ), __( 'active %s', 'buddypress' ) );
 	}
 
 	/**
 	 * Populates extra fields such as group and friendship counts.
 	 */
-	function populate_extras() {
+	public function populate_extras() {
 
 		if ( bp_is_active( 'friends' ) ) {
 			$this->total_friends = BP_Friends_Friendship::total_friend_count( $this->id );
@@ -788,20 +831,59 @@ class BP_Core_User {
 		}
 	}
 
-	function get_profile_data() {
+	/**
+	 * Fetch xprofile data for the current user.
+	 *
+	 * @see BP_XProfile_ProfileData::get_all_for_user() for description of
+	 *      return value.
+	 *
+	 * @return array See {@link BP_XProfile_Profile_Data::get_all_for_user()}.
+	 */
+	public function get_profile_data() {
 		return BP_XProfile_ProfileData::get_all_for_user( $this->id );
 	}
 
 	/** Static Methods ********************************************************/
 
-	function get_users( $type, $limit = 0, $page = 1, $user_id = 0, $include = false, $search_terms = false, $populate_extras = true, $exclude = false, $meta_key = false, $meta_value = false ) {
+	/**
+	 * Get a list of users that match the query parameters.
+	 *
+	 * Since BuddyPress 1.7, use {@link BP_User_Query} instead.
+	 *
+	 * @deprecated 1.7.0 Use {@link BP_User_Query}.
+	 *
+	 * @see BP_User_Query for a description of parameters, most of which
+	 *      are used there in the same way.
+	 *
+	 * @param string $type See {@link BP_User_Query}.
+	 * @param int $limit See {@link BP_User_Query}. Default: 0.
+	 * @param int $page See {@link BP_User_Query}. Default: 1.
+	 * @param int $user_id See {@link BP_User_Query}. Default: 0.
+	 * @param mixed $include See {@link BP_User_Query}. Default: false.
+	 * @param string|bool $search_terms See {@link BP_User_Query}.
+	 *        Default: false.
+	 * @param bool $populate_extras See {@link BP_User_Query}.
+	 *        Default: true.
+	 * @param mixed $exclude See {@link BP_User_Query}. Default: false.
+	 * @param string|bool $meta_key See {@link BP_User_Query}.
+	 *        Default: false.
+	 * @param string|bool $meta_value See {@link BP_User_Query}.
+	 *        Default: false.
+	 * @return array {
+	 *     @type int $total_users Total number of users matched by query
+	 *           params.
+	 *     @type array $paged_users The current page of users matched by
+	 *           query params.
+	 * }
+	 */
+	public static function get_users( $type, $limit = 0, $page = 1, $user_id = 0, $include = false, $search_terms = false, $populate_extras = true, $exclude = false, $meta_key = false, $meta_value = false ) {
 		global $wpdb, $bp;
 
 		_deprecated_function( __METHOD__, '1.7', 'BP_User_Query' );
 
 		$sql = array();
 
-		$sql['select_main'] = "SELECT DISTINCT u.ID as id, u.user_registered, u.user_nicename, u.user_login, u.display_name, u.user_email";
+		$sql['select_main'] = "SELECT u.ID as id, u.user_registered, u.user_nicename, u.user_login, u.display_name, u.user_email";
 
 		if ( 'active' == $type || 'online' == $type || 'newest' == $type  ) {
 			$sql['select_active'] = ", um.meta_value as last_activity";
@@ -943,7 +1025,7 @@ class BP_Core_User {
 			unset( $sql['pagination'] );
 		}
 
-		array_unshift( $sql, "SELECT COUNT(DISTINCT u.ID)" );
+		array_unshift( $sql, "SELECT COUNT(u.ID)" );
 
 		// Get total user results
 		$total_users_sql = apply_filters( 'bp_core_get_total_users_sql', join( ' ', (array) $sql ), $sql );
@@ -969,19 +1051,22 @@ class BP_Core_User {
 
 
 	/**
-	 * Fetches the user details for all the users who username starts with the letter given.
+	 * Fetch the details for all users whose usernames start with the given letter.
+	 *
+	 * @global BuddyPress $bp The one true BuddyPress instance.
+	 * @global wpdb $wpdb WordPress database object.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
-	 * @global wpdb $wpdb WordPress database object
 	 * @param string $letter The letter the users names are to start with.
-	 * @param integer $limit The number of users we wish to retrive.
-	 * @param integer $page The page number we are currently on, used in conjunction with $limit to get the start position for the limit.
-	 * @param boolean $populate_extras Populate extra user fields?
-	 * @param string $exclude Comma-separated IDs of users whose results aren't to be fetched.
+	 * @param int $limit The number of users we wish to retrive.
+	 * @param int $page The page number we are currently on, used in
+	 *        conjunction with $limit to get the start position for the
+	 *        limit.
+	 * @param bool $populate_extras Populate extra user fields?
+	 * @param string $exclude Comma-separated IDs of users whose results
+	 *        aren't to be fetched.
 	 * @return mixed False on error, otherwise associative array of results.
-	 * @static
 	 */
-	function get_users_by_letter( $letter, $limit = null, $page = 1, $populate_extras = true, $exclude = '' ) {
+	public static function get_users_by_letter( $letter, $limit = null, $page = 1, $populate_extras = true, $exclude = '' ) {
 		global $bp, $wpdb;
 
 		$pag_sql = '';
@@ -1036,17 +1121,19 @@ class BP_Core_User {
 	}
 
 	/**
-	 * Get details of specific users from the database
+	 * Get details of specific users from the database.
 	 *
-	 * @global wpdb $wpdb WordPress database object
-	 * @param array $user_ids The user IDs of the users who we wish to fetch information on.
-	 * @param integer $limit The limit of results we want.
-	 * @param integer $page The page we are on for pagination.
-	 * @param boolean $populate_extras Populate extra user fields?
-	 * @return array Associative array
-	 * @static
+	 * Use {@link BP_User_Query} with the 'user_ids' param instead.
+	 *
+	 * @global wpdb $wpdb WordPress database object.
+	 * @param array $user_ids The user IDs of the users who we wish to
+	 *        fetch information on.
+	 * @param int $limit The limit of results we want.
+	 * @param int $page The page we are on for pagination.
+	 * @param bool $populate_extras Populate extra user fields?
+	 * @return array Associative array.
 	 */
-	function get_specific_users( $user_ids, $limit = null, $page = 1, $populate_extras = true ) {
+	public static function get_specific_users( $user_ids, $limit = null, $page = 1, $populate_extras = true ) {
 		global $wpdb;
 
 		$pag_sql = '';
@@ -1056,8 +1143,8 @@ class BP_Core_User {
 		$user_ids   = implode( ',', wp_parse_id_list( $user_ids ) );
 		$status_sql = bp_core_get_status_sql();
 
-		$total_users_sql = apply_filters( 'bp_core_get_specific_users_count_sql', "SELECT COUNT(DISTINCT ID) FROM {$wpdb->users} WHERE {$status_sql} AND ID IN ({$user_ids})" );
-		$paged_users_sql = apply_filters( 'bp_core_get_specific_users_count_sql', "SELECT DISTINCT ID as id, user_registered, user_nicename, user_login, user_email FROM {$wpdb->users} WHERE {$status_sql} AND ID IN ({$user_ids}) {$pag_sql}" );
+		$total_users_sql = apply_filters( 'bp_core_get_specific_users_count_sql', "SELECT COUNT(ID) FROM {$wpdb->users} WHERE {$status_sql} AND ID IN ({$user_ids})" );
+		$paged_users_sql = apply_filters( 'bp_core_get_specific_users_count_sql', "SELECT ID as id, user_registered, user_nicename, user_login, user_email FROM {$wpdb->users} WHERE {$status_sql} AND ID IN ({$user_ids}) {$pag_sql}" );
 
 		$total_users = $wpdb->get_var( $total_users_sql );
 		$paged_users = $wpdb->get_results( $paged_users_sql );
@@ -1081,16 +1168,17 @@ class BP_Core_User {
 	/**
 	 * Find users who match on the value of an xprofile data.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
-	 * @global wpdb $wpdb WordPress database object
-	 * @param string $search_terms The terms to search the profile table value column for.
+	 * @global BuddyPress $bp The one true BuddyPress instance.
+	 * @global wpdb $wpdb WordPress database object.
+	 *
+	 * @param string $search_terms The terms to search the profile table
+	 *        value column for.
 	 * @param integer $limit The limit of results we want.
 	 * @param integer $page The page we are on for pagination.
 	 * @param boolean $populate_extras Populate extra user fields?
-	 * @return array Associative array
-	 * @static
+	 * @return array Associative array.
 	 */
-	function search_users( $search_terms, $limit = null, $page = 1, $populate_extras = true ) {
+	public static function search_users( $search_terms, $limit = null, $page = 1, $populate_extras = true ) {
 		global $bp, $wpdb;
 
 		$user_ids = array();
@@ -1124,15 +1212,15 @@ class BP_Core_User {
 	 *
 	 * Accepts multiple user IDs to fetch data for.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
-	 * @global wpdb $wpdb WordPress database object
-	 * @param array $paged_users an array of stdClass containing the users
-	 * @param string $user_ids the user ids to select information about
-	 * @param string $type the type of fields we wish to get
+	 * @global BuddyPress $bp The one true BuddyPress instance.
+	 * @global wpdb $wpdb WordPress database object.
+	 *
+	 * @param array $paged_users An array of stdClass containing the users.
+	 * @param string $user_ids The user ids to select information about.
+	 * @param string $type The type of fields we wish to get.
 	 * @return mixed False on error, otherwise associative array of results.
-	 * @static
 	 */
-	function get_user_extras( &$paged_users, &$user_ids, $type = false ) {
+	public static function get_user_extras( &$paged_users, &$user_ids, $type = false ) {
 		global $bp, $wpdb;
 
 		if ( empty( $user_ids ) )
@@ -1210,12 +1298,12 @@ class BP_Core_User {
 	/**
 	 * Get WordPress user details for a specified user.
 	 *
-	 * @global wpdb $wpdb WordPress database object
-	 * @param integer $user_id User ID
-	 * @return array Associative array
-	 * @static
+	 * @global wpdb $wpdb WordPress database object.
+	 *
+	 * @param integer $user_id User ID.
+	 * @return array Associative array.
 	 */
-	function get_core_userdata( $user_id ) {
+	public static function get_core_userdata( $user_id ) {
 		global $wpdb;
 
 		if ( !$user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->users} WHERE ID = %d LIMIT 1", $user_id ) ) )
@@ -1223,16 +1311,194 @@ 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;
+		}
+
+		// get cache for single user only
+		if ( ! is_array( $user_id ) ) {
+			$cache = wp_cache_get( $user_id, 'bp_last_activity' );
+
+			if ( false !== $cache ) {
+				return $cache;
+			}
+		}
+
+		$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;
+
+		$activity = self::get_last_activity( $user_id );
+
+		if ( ! empty( $activity ) ) {
+			$updated = $wpdb->update(
+				$table_name,
+
+				// Data to update
+				array(
+					'date_recorded' => $time,
+				),
+
+				// WHERE
+				array(
+					'id' => $activity[ $user_id ]['activity_id'],
+				),
+
+				// Data sanitization format
+				array(
+					'%s',
+				),
+
+				// WHERE sanitization format
+				array(
+					'%d',
+				)
+			);
+
+			// add new date to existing activity entry for caching
+			$activity[ $user_id ]['date_recorded'] = $time;
+
+		} else {
+			$updated = $wpdb->insert(
+				$table_name,
+
+				// Data
+				array(
+					'user_id'       => $user_id,
+					'component'     => buddypress()->members->id,
+					'type'          => 'last_activity',
+					'action'        => '',
+					'content'       => '',
+					'primary_link'  => '',
+					'item_id'       => 0,
+					'date_recorded' => $time,
+				),
+
+				// Data sanitization format
+				array(
+					'%d',
+					'%s',
+					'%s',
+					'%s',
+					'%s',
+					'%s',
+					'%d',
+					'%s',
+				)
+			);
+
+			// setup activity array for caching
+			// view the foreach loop in the get_last_activity() method for format
+			$activity = array();
+			$activity[ $user_id ] = array(
+				'user_id'       => $user_id,
+				'date_recorded' => $time,
+				'activity_id'   => $wpdb->insert_id,
+			);
+		}
+
+		// set cache
+		wp_cache_set( $user_id, $activity, 'bp_last_activity' );
+
+		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',
+			)
+		);
+
+		wp_cache_delete( $user_id, 'bp_last_activity' );
+
+		return $deleted;
+	}
 }
 
 
 /**
- * BP_Core_Notification class can be used by any component.
- * It will handle the fetching, saving and deleting of a user notification.
+ * BP_Core_Notification is deprecated.
+ *
+ * Use BP_Notifications_Notification instead.
  *
  * @package BuddyPress Core
+ * @deprecated since BuddyPress (1.9)
  */
-
 class BP_Core_Notification {
 
 	/**
@@ -1240,56 +1506,56 @@ class BP_Core_Notification {
 	 *
 	 * @var integer
 	 */
-	var $id;
+	public $id;
 
 	/**
 	 * The ID to which the notification relates to within the component.
 	 *
 	 * @var integer
 	 */
-	var $item_id;
+	public $item_id;
 
 	/**
 	 * The secondary ID to which the notification relates to within the component.
 	 *
 	 * @var integer
 	 */
-	var $secondary_item_id = null;
+	public $secondary_item_id = null;
 
 	/**
 	 * The user ID for who the notification is for.
 	 *
 	 * @var integer
 	 */
-	var $user_id;
+	public $user_id;
 
 	/**
 	 * The name of the component that the notification is for.
 	 *
 	 * @var string
 	 */
-	var $component_name;
+	public $component_name;
 
 	/**
 	 * The action within the component which the notification is related to.
 	 *
 	 * @var string
 	 */
-	var $component_action;
+	public $component_action;
 
 	/**
 	 * The date the notification was created.
 	 *
 	 * @var string
 	 */
-	var $date_notified;
+	public $date_notified;
 
 	/**
 	 * Is the notification new or has it already been read.
 	 *
 	 * @var boolean
 	 */
-	var $is_new;
+	public $is_new;
 
 	/** Public Methods ********************************************************/
 
@@ -1298,7 +1564,7 @@ class BP_Core_Notification {
 	 *
 	 * @param integer $id
 	 */
-	function __construct( $id = 0 ) {
+	public function __construct( $id = 0 ) {
 		if ( !empty( $id ) ) {
 			$this->id = $id;
 			$this->populate();
@@ -1312,7 +1578,7 @@ class BP_Core_Notification {
 	 * @global wpdb $wpdb WordPress database object
 	 * @return bool Success or failure
 	 */
-	function save() {
+	public function save() {
 		global $bp, $wpdb;
 
 		// Update
@@ -1340,7 +1606,7 @@ class BP_Core_Notification {
 	 * @global BuddyPress $bp The one true BuddyPress instance
 	 * @global wpdb $wpdb WordPress database object
 	 */
-	function populate() {
+	public function populate() {
 		global $bp, $wpdb;
 
 		if ( $notification = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->core->table_name_notifications} WHERE id = %d", $this->id ) ) ) {
@@ -1356,7 +1622,7 @@ class BP_Core_Notification {
 
 	/** Static Methods ********************************************************/
 
-	function check_access( $user_id, $notification_id ) {
+	public static function check_access( $user_id, $notification_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->core->table_name_notifications} WHERE id = %d AND user_id = %d", $notification_id, $user_id ) );
@@ -1372,7 +1638,7 @@ class BP_Core_Notification {
 	 * @return array Associative array
 	 * @static
 	 */
-	function get_all_for_user( $user_id, $status = 'is_new' ) {
+	public static function get_all_for_user( $user_id, $status = 'is_new' ) {
 		global $bp, $wpdb;
 
 		$is_new = ( 'is_new' == $status ) ? ' AND is_new = 1 ' : '';
@@ -1390,7 +1656,7 @@ class BP_Core_Notification {
 	 * @param string $component_action
 	 * @static
 	 */
-	function delete_for_user_by_type( $user_id, $component_name, $component_action ) {
+	public static function delete_for_user_by_type( $user_id, $component_name, $component_action ) {
 		global $bp, $wpdb;
 
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->core->table_name_notifications} WHERE user_id = %d AND component_name = %s AND component_action = %s", $user_id, $component_name, $component_action ) );
@@ -1408,7 +1674,7 @@ class BP_Core_Notification {
 	 * @param integer $secondary_item_id (optional) The secondary item id of the notifications that we wish to use to delete.
 	 * @static
 	 */
-	function delete_for_user_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false ) {
+	public static function delete_for_user_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false ) {
 		global $bp, $wpdb;
 
 		$secondary_item_sql = !empty( $secondary_item_id ) ? $wpdb->prepare( " AND secondary_item_id = %d", $secondary_item_id ) : '';
@@ -1426,7 +1692,7 @@ class BP_Core_Notification {
 	 * @param string $component_action The action of the component the notification was sent from.
 	 * @static
 	 */
-	function delete_from_user_by_type( $user_id, $component_name, $component_action ) {
+	public static function delete_from_user_by_type( $user_id, $component_name, $component_action ) {
 		global $bp, $wpdb;
 
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->core->table_name_notifications} WHERE item_id = %d AND component_name = %s AND component_action = %s", $user_id, $component_name, $component_action ) );
@@ -1443,7 +1709,7 @@ class BP_Core_Notification {
 	 * @param string $secondary_item_id Optional secondary item id that the notifications are to have.
 	 * @static
 	 */
-	function delete_all_by_type( $item_id, $component_name, $component_action, $secondary_item_id ) {
+	public static function delete_all_by_type( $item_id, $component_name, $component_action, $secondary_item_id ) {
 		global $bp, $wpdb;
 
 		if ( $component_action )
@@ -1461,40 +1727,51 @@ class BP_Core_Notification {
 }
 
 /**
- * BP_Button
- *
- * API to create BuddyPress buttons
+ * API to create BuddyPress buttons.
  *
- * component: Which component this button is for
- * must_be_logged_in: Button only appears for logged in users
- * block_self: Button will not appear when viewing your own profile.
- * wrapper: div|span|p|li|false for no wrapper
- * wrapper_id: The DOM ID of the button wrapper
- * wrapper_class: The DOM class of the button wrapper
- * link_href: The destination link of the button
- * link_title: Title of the button
- * link_id: The DOM ID of the button
- * link_class: The DOM class of the button
- * link_rel: The DOM rel of the button
- * link_text: The text of the button
- * contents: The contents of the button
- *
- * @package BuddyPress Core
  * @since BuddyPress (1.2.6)
+ *
+ * @param array $args {
+ *     Array of arguments.
+ *     @type string $id String describing the button type.
+ *     @type string $component The name of the component the button belongs to.
+ *           Default: 'core'.
+ *     @type bool $must_be_logged_in Optional. Does the user need to be logged
+ *           in to see this button? Default: true.
+ *     @type bool $block_self Optional. True if the button should be hidden
+ *           when a user is viewing his own profile. Default: true.
+ *     @type string|bool $wrapper Optional. HTML element type that should wrap
+ *           the button: 'div', 'span', 'p', or 'li'. False for no wrapper at
+ *           all. Default: 'div'.
+ *     @type string $wrapper_id Optional. DOM ID of the button wrapper element.
+ *           Default: ''.
+ *     @type string $wrapper_class Optional. DOM class of the button wrapper
+ *           element. Default: ''.
+ *     @type string $link_href Optional. Destination link of the button.
+ *           Default: ''.
+ *     @type string $link_class Optional. DOM class of the button. Default: ''.
+ *     @type string $link_id Optional. DOM ID of the button. Default: ''.
+ *     @type string $link_rel Optional. DOM 'rel' attribute of the button.
+ *           Default: ''.
+ *     @type string $link_title Optional. Title attribute of the button.
+ *           Default: ''.
+ *     @type string $link_text Optional. Text to appear on the button.
+ *           Default: ''.
+ * }
  */
 class BP_Button {
 
 	/** Button properties *****************************************************/
 
 	/**
-	 * The button ID
+	 * The button ID.
 	 *
-	 * @var integer
+	 * @var string
 	 */
 	public $id = '';
 
 	/**
-	 * The component name that button belongs to.
+	 * The name of the component that the button belongs to.
 	 *
 	 * @var string
 	 */
@@ -1503,37 +1780,35 @@ class BP_Button {
 	/**
 	 * Does the user need to be logged in to see this button?
 	 *
-	 * @var boolean
+	 * @var bool
 	 */
 	public $must_be_logged_in = true;
 
 	/**
-	 * True or false if the button should not be displayed while viewing your
-	 * own profile.
+	 * Whether the button should be hidden when viewing your own profile.
 	 *
-	 * @var boolean
+	 * @var bool
 	 */
 	public $block_self = true;
 
 	/** Wrapper ***************************************************************/
 
 	/**
-	 * What type of DOM element to use for a wrapper.
-	 *
+	 * The type of DOM element to use for a wrapper.
 	 *
-	 * @var mixed div|span|p|li, or false for no wrapper
+	 * @var string|bool 'div', 'span', 'p', 'li', or false for no wrapper.
 	 */
 	public $wrapper = 'div';
 
 	/**
-	 * The DOM class of the button wrapper
+	 * The DOM class of the button wrapper.
 	 *
 	 * @var string
 	 */
 	public $wrapper_class = '';
 
 	/**
-	 * The DOM ID of the button wrapper
+	 * The DOM ID of the button wrapper.
 	 *
 	 * @var string
 	 */
@@ -1542,42 +1817,42 @@ class BP_Button {
 	/** Button ****************************************************************/
 
 	/**
-	 * The destination link of the button
+	 * The destination link of the button.
 	 *
 	 * @var string
 	 */
 	public $link_href = '';
 
 	/**
-	 * The DOM class of the button link
+	 * The DOM class of the button link.
 	 *
 	 * @var string
 	 */
 	public $link_class = '';
 
 	/**
-	 * The DOM ID of the button link
+	 * The DOM ID of the button link.
 	 *
 	 * @var string
 	 */
 	public $link_id = '';
 
 	/**
-	 * The DOM rel value of the button link
+	 * The DOM rel value of the button link.
 	 *
 	 * @var string
 	 */
 	public $link_rel = '';
 
 	/**
-	 * Title of the button link
+	 * Title of the button link.
 	 *
 	 * @var string
 	 */
 	public $link_title = '';
 
 	/**
-	 * The contents of the button link
+	 * The contents of the button link.
 	 *
 	 * @var string
 	 */
@@ -1590,12 +1865,13 @@ class BP_Button {
 	/** Methods ***************************************************************/
 
 	/**
-	 * Builds the button based on class parameters:
+	 * Builds the button based on class parameters.
 	 *
 	 * @since BuddyPress (1.2.6)
 	 *
-	 * @param array $args
-	 * @return bool False if not allowed
+	 * @param array $args See {@BP_Button}.
+	 * @return bool|null Returns false when the button is not allowed for
+	 *         the current context.
 	 */
 	public function __construct( $args = '' ) {
 
@@ -1668,18 +1944,18 @@ class BP_Button {
 	}
 
 	/**
-	 * Return contents of button
+	 * Return the markup for the generated button.
 	 *
 	 * @since BuddyPress (1.2.6)
 	 *
-	 * @return string
+	 * @return string Button markup.
 	 */
 	public function contents() {
 		return $this->contents;
 	}
 
 	/**
-	 * Output contents of button
+	 * Output the markup of button.
 	 *
 	 * @since BuddyPress (1.2.6)
 	 */
@@ -1690,12 +1966,12 @@ class BP_Button {
 }
 
 /**
- * BP_Embed
+ * Enable oEmbeds in BuddyPress contexts.
  *
  * Extends WP_Embed class for use with BuddyPress.
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
  * @see WP_Embed
  */
 class BP_Embed extends WP_Embed {
@@ -1703,9 +1979,9 @@ class BP_Embed extends WP_Embed {
 	/**
 	 * Constructor
 	 *
-	 * @global unknown $wp_embed
+	 * @global WP_Embed $wp_embed
 	 */
-	function __construct() {
+	public function __construct() {
 		global $wp_embed;
 
 		// Make sure we populate the WP_Embed handlers array.
@@ -1740,9 +2016,12 @@ class BP_Embed extends WP_Embed {
 	/**
 	 * The {@link do_shortcode()} callback function.
 	 *
-	 * Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of the registered embed handlers.
-	 * Next, checks the URL against the regex of registered {@link WP_oEmbed} providers if oEmbed discovery is false.
-	 * If none of the regex matches and it's enabled, then the URL will be passed to {@link BP_Embed::parse_oembed()} for oEmbed parsing.
+	 * Attempts to convert a URL into embed HTML. Starts by checking the
+	 * URL against the regex of the registered embed handlers. Next, checks
+	 * the URL against the regex of registered {@link WP_oEmbed} providers
+	 * if oEmbed discovery is false. If none of the regex matches and it's
+	 * enabled, then the URL will be passed to {@link BP_Embed::parse_oembed()}
+	 * for oEmbed parsing.
 	 *
 	 * @uses wp_parse_args()
 	 * @uses wp_embed_defaults()
@@ -1754,7 +2033,7 @@ class BP_Embed extends WP_Embed {
 	 * @param string $url The URL attempting to be embeded.
 	 * @return string The embed HTML on success, otherwise the original URL.
 	 */
-	function shortcode( $attr, $url = '' ) {
+	public function shortcode( $attr, $url = '' ) {
 		if ( empty( $url ) )
 			return '';
 
@@ -1806,20 +2085,25 @@ class BP_Embed extends WP_Embed {
 	}
 
 	/**
-	 * Base function so BP components / plugins can parse links to be embedded.
+	 * Base function so BP components/plugins can parse links to be embedded.
+	 *
 	 * View an example to add support in {@link bp_activity_embed()}.
 	 *
 	 * @uses apply_filters() Filters cache.
 	 * @uses do_action() To save cache.
-	 * @uses wp_oembed_get() Connects to oEmbed provider and returns HTML on success.
-	 * @uses WP_Embed::maybe_make_link() Process URL for hyperlinking on oEmbed failure.
+	 * @uses wp_oembed_get() Connects to oEmbed provider and returns HTML
+	 *       on success.
+	 * @uses WP_Embed::maybe_make_link() Process URL for hyperlinking on
+	 *       oEmbed failure.
+	 *
 	 * @param int $id ID to do the caching for.
 	 * @param string $url The URL attempting to be embedded.
 	 * @param array $attr Shortcode attributes from {@link WP_Embed::shortcode()}.
-	 * @param array $rawattr Untouched shortcode attributes from {@link WP_Embed::shortcode()}.
+	 * @param array $rawattr Untouched shortcode attributes from
+	 *        {@link WP_Embed::shortcode()}.
 	 * @return string The embed HTML on success, otherwise the original URL.
 	 */
-	function parse_oembed( $id, $url, $attr, $rawattr ) {
+	public function parse_oembed( $id, $url, $attr, $rawattr ) {
 		$id = intval( $id );
 
 		if ( $id ) {
@@ -1854,19 +2138,24 @@ class BP_Embed extends WP_Embed {
 }
 
 /**
- * Create HTML list of BP nav items
+ * Create HTML list of BP nav items.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 class BP_Walker_Nav_Menu extends Walker_Nav_Menu {
+
 	/**
-	 * @since BuddyPress (1.7)
+	 * Description of fields indexes for building markup.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 * @var array
 	 */
 	var $db_fields = array( 'id' => 'css_id', 'parent' => 'parent' );
 
 	/**
-	 * @since BuddyPress (1.7)
+	 * Tree type.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 * @var string
 	 */
 	var $tree_type = array();
@@ -1874,21 +2163,28 @@ class BP_Walker_Nav_Menu extends Walker_Nav_Menu {
 	/**
 	 * Display array of elements hierarchically.
 	 *
-	 * This method is almost identical to the version in {@link Walker::walk()}. The only change is on one line
-	 * which has been commented. An IF was comparing 0 to a non-empty string which was preventing child elements
+	 * This method is almost identical to the version in {@link Walker::walk()}.
+	 * The only change is on one line which has been commented. An IF was
+	 * comparing 0 to a non-empty string which was preventing child elements
 	 * being grouped under their parent menu element.
 	 *
-	 * This caused a problem for BuddyPress because our primary/secondary navigations doesn't have a unique numerical
-	 * ID that describes a hierarchy (we use a slug). Obviously, WordPress Menus use Posts, and those have ID/post_parent.
+	 * This caused a problem for BuddyPress because our primary/secondary
+	 * navigations don't have a unique numerical ID that describes a
+	 * hierarchy (we use a slug). Obviously, WordPress Menus use Posts, and
+	 * those have ID/post_parent.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @param array $elements
-	 * @param int $max_depth
-	 * @return string
 	 * @see Walker::walk()
-	 * @since BuddyPress (1.7)
+	 *
+	 * @param array $elements See {@link Walker::walk()}.
+	 * @param int $max_depth See {@link Walker::walk()}.
+	 * @return string See {@link Walker::walk()}.
 	 */
-	function walk( $elements, $max_depth ) {
-		$args   = array_slice( func_get_args(), 2 );
+	public function walk( $elements, $max_depth ) {
+		$func_args = func_get_args();
+
+		$args   = array_slice( $func_args, 2 );
 		$output = '';
 
 		if ( $max_depth < -1 ) // invalid parameter
@@ -1965,16 +2261,21 @@ class BP_Walker_Nav_Menu extends Walker_Nav_Menu {
 	}
 
 	/**
-	 * Displays the current <li> that we are on.
+	 * Display the current <li> that we are on.
+	 *
+	 * @see Walker::start_el() for complete description of parameters .
 	 *
-	 * @param string $output Passed by reference. Used to append additional content.
+	 * @since BuddyPress (1.7.0)
+	 *
+	 * @param string $output Passed by reference. Used to append
+	 *        additional content.
 	 * @param object $item Menu item data object.
-	 * @param int $depth Depth of menu item. Used for padding. Optional, defaults to 0.
-	 * @param array $args Optional
+	 * @param int $depth Depth of menu item. Used for padding. Optional,
+	 *        defaults to 0.
+	 * @param array $args Optional. See {@link Walker::start_el()}.
 	 * @param int $current_page Menu item ID. Optional.
-	 * @since BuddyPress (1.7)
 	 */
-	function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
+	public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
 		// If we're someway down the tree, indent the HTML with the appropriate number of tabs
 		$indent = $depth ? str_repeat( "\t", $depth ) : '';
 
@@ -2004,3 +2305,110 @@ class BP_Walker_Nav_Menu extends Walker_Nav_Menu {
 		$output .= apply_filters( 'bp_walker_nav_menu_start_el', $item_output, $item, $depth, $args );
 	}
 }
+
+/**
+ * Create a set of BuddyPress-specific links for use in the Menus admin UI.
+ *
+ * Borrowed heavily from {@link Walker_Nav_Menu_Checklist}, but modified so as not
+ * to require an actual post type or taxonomy, and to force certain CSS classes
+ *
+ * @since BuddyPress (1.9.0)
+ */
+class BP_Walker_Nav_Menu_Checklist extends Walker_Nav_Menu {
+
+	/**
+	 * Constructor.
+	 *
+	 * @see Walker_Nav_Menu::__construct() for a description of parameters.
+	 *
+	 * @param array $fields See {@link Walker_Nav_Menu::__construct()}.
+	 */
+	public function __construct( $fields = false ) {
+		if ( $fields ) {
+			$this->db_fields = $fields;
+		}
+	}
+
+	/**
+	 * Create the markup to start a tree level.
+	 *
+	 * @see Walker_Nav_Menu::start_lvl() for description of parameters.
+	 *
+	 * @param string $output See {@Walker_Nav_Menu::start_lvl()}.
+	 * @param int $depth See {@Walker_Nav_Menu::start_lvl()}.
+	 * @param array $args See {@Walker_Nav_Menu::start_lvl()}.
+	 */
+	public function start_lvl( &$output, $depth = 0, $args = array() ) {
+		$indent = str_repeat( "\t", $depth );
+		$output .= "\n$indent<ul class='children'>\n";
+	}
+
+	/**
+	 * Create the markup to end a tree level.
+	 *
+	 * @see Walker_Nav_Menu::end_lvl() for description of parameters.
+	 *
+	 * @param string $output See {@Walker_Nav_Menu::end_lvl()}.
+	 * @param int $depth See {@Walker_Nav_Menu::end_lvl()}.
+	 * @param array $args See {@Walker_Nav_Menu::end_lvl()}.
+	 */
+	public function end_lvl( &$output, $depth = 0, $args = array() ) {
+		$indent = str_repeat( "\t", $depth );
+		$output .= "\n$indent</ul>";
+	}
+
+	/**
+	 * Create the markup to start an element.
+	 *
+	 * @see Walker::start_el() for description of parameters.
+	 *
+	 * @param string $output Passed by reference. Used to append additional
+	 *        content.
+	 * @param object $item Menu item data object.
+	 * @param int $depth Depth of menu item. Used for padding.
+	 * @param object $args See {@Walker::start_el()}.
+	 * @param int $id See {@Walker::start_el()}.
+	 */
+	function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
+		global $_nav_menu_placeholder;
+
+		$_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval($_nav_menu_placeholder) - 1 : -1;
+		$possible_object_id = isset( $item->post_type ) && 'nav_menu_item' == $item->post_type ? $item->object_id : $_nav_menu_placeholder;
+		$possible_db_id = ( ! empty( $item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $item->ID : 0;
+
+		$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
+
+		$output .= $indent . '<li>';
+		$output .= '<label class="menu-item-title">';
+		$output .= '<input type="checkbox" class="menu-item-checkbox';
+
+		if ( property_exists( $item, 'label' ) ) {
+			$title = $item->label;
+		}
+
+		$output .= '" name="menu-item[' . $possible_object_id . '][menu-item-object-id]" value="'. esc_attr( $item->object_id ) .'" /> ';
+		$output .= isset( $title ) ? esc_html( $title ) : esc_html( $item->title );
+		$output .= '</label>';
+
+		if ( empty( $item->url ) ) {
+			$item->url = $item->guid;
+		}
+
+		if ( ! in_array( array( 'bp-menu', 'bp-'. $item->post_excerpt .'-nav' ), $item->classes ) ) {
+			$item->classes[] = 'bp-menu';
+			$item->classes[] = 'bp-'. $item->post_excerpt .'-nav';
+		}
+
+		// Menu item hidden fields
+		$output .= '<input type="hidden" class="menu-item-db-id" name="menu-item[' . $possible_object_id . '][menu-item-db-id]" value="' . $possible_db_id . '" />';
+		$output .= '<input type="hidden" class="menu-item-object" name="menu-item[' . $possible_object_id . '][menu-item-object]" value="'. esc_attr( $item->object ) .'" />';
+		$output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. esc_attr( $item->menu_item_parent ) .'" />';
+		$output .= '<input type="hidden" class="menu-item-type" name="menu-item[' . $possible_object_id . '][menu-item-type]" value="custom" />';
+		$output .= '<input type="hidden" class="menu-item-title" name="menu-item[' . $possible_object_id . '][menu-item-title]" value="'. esc_attr( $item->title ) .'" />';
+		$output .= '<input type="hidden" class="menu-item-url" name="menu-item[' . $possible_object_id . '][menu-item-url]" value="'. esc_attr( $item->url ) .'" />';
+		$output .= '<input type="hidden" class="menu-item-target" name="menu-item[' . $possible_object_id . '][menu-item-target]" value="'. esc_attr( $item->target ) .'" />';
+		$output .= '<input type="hidden" class="menu-item-attr_title" name="menu-item[' . $possible_object_id . '][menu-item-attr_title]" value="'. esc_attr( $item->attr_title ) .'" />';
+		$output .= '<input type="hidden" class="menu-item-classes" name="menu-item[' . $possible_object_id . '][menu-item-classes]" value="'. esc_attr( implode( ' ', $item->classes ) ) .'" />';
+		$output .= '<input type="hidden" class="menu-item-xfn" name="menu-item[' . $possible_object_id . '][menu-item-xfn]" value="'. esc_attr( $item->xfn ) .'" />';
+	}
+}
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-component.php b/wp-content/plugins/buddypress/bp-core/bp-core-component.php
index a82c1145c7b32254b23124acff0c3533e37abb55..c16c17cf2017fa2e5d2bf4202e23d170f877fd4f 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-component.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-component.php
@@ -1,11 +1,17 @@
 <?php
+/**
+ * Component classes.
+ *
+ * @package BuddyPress
+ * @subpackage Core
+ */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
 if ( !class_exists( 'BP_Component' ) ) :
 /**
- * BuddyPress Component Class
+ * BuddyPress Component Class.
  *
  * The BuddyPress component class is responsible for simplifying the creation
  * of components that share similar behaviors and routines. It is used
@@ -15,88 +21,131 @@ if ( !class_exists( 'BP_Component' ) ) :
  * @package BuddyPress
  * @subpackage Component
  *
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  */
 class BP_Component {
 
 	/** Variables *************************************************************/
 
 	/**
-	 * @var string Unique name (for internal identification)
+	 * Translatable name for the component.
+	 *
 	 * @internal
+	 * @var string $name
 	 */
 	public $name = '';
 
 	/**
-	 * @var Unique ID (normally for custom post type)
+	 * Unique ID for the component.
+	 *
+	 * @var string $id
 	 */
 	public $id = '';
 
 	/**
-	 * @var string Unique slug (used in query string and permalinks)
+	 * Unique slug for the component, for use in query strings and URLs.
+	 *
+	 * @var string $slug
 	 */
 	public $slug = '';
 
 	/**
-	 * @var bool Does this component need a top-level directory?
+	 * Does the component need a top-level directory?
+	 *
+	 * @var bool $has_directory
 	 */
 	public $has_directory = false;
 
 	/**
-	 * @var string The path to the component's files
+	 * The path to the component's files.
+	 *
+	 * @var string $path
 	 */
 	public $path = '';
 
 	/**
-	 * @var WP_Query The loop for this component
+	 * The WP_Query loop for this component.
+	 *
+	 * @var WP_Query $query
 	 */
 	public $query = false;
 
 	/**
-	 * @var string The current ID of the queried object
+	 * The current ID of the queried object.
+	 *
+	 * @var string $current_id
 	 */
 	public $current_id = '';
 
 	/**
-	 * @var string Function to call for notifications
+	 * Callback for formatting notifications.
+	 *
+	 * @var callable $notification_callback
 	 */
 	public $notification_callback = '';
 
 	/**
-	 * @var array WordPress Toolbar links
+	 * WordPress Toolbar links.
+	 *
+	 * @var array $admin_menu
 	 */
 	public $admin_menu = '';
 
 	/**
-	 * Search input box placeholder string for the component
+	 * Placeholder text for component directory search box.
 	 *
-	 * @since BuddyPress (1.5)
-	 * @var string
+	 * @since BuddyPress (1.5.0)
+	 * @var string $search_string
 	 */
 	public $search_string = '';
 
 	/**
-	 * Component's root slug
+	 * Root slug for the component.
 	 *
-	 * @since BuddyPress (1.5)
-	 * @var string
+	 * @since BuddyPress (1.5.0)
+	 * @var string $root_slug
 	 */
 	public $root_slug = '';
 
+	/**
+	 * Metadata tables for the component (if applicable)
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @var array
+	 */
+	public $meta_tables = array();
+
+	/**
+	 * Global tables for the component (if applicable)
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @var array
+	 */
+	public $global_tables = array();
+
 	/** Methods ***************************************************************/
 
 	/**
-	 * Component loader
+	 * Component loader.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @param string $id Unique ID (for internal identification). Letters, numbers, and underscores only
-	 * @param string $name Unique name. This should be a translatable name, eg __( 'Groups', 'buddypress' )
-	 * @param string $path The file path for the component's files. Used by BP_Component::includes()
+	 * @uses BP_Component::setup_actions() Set up the hooks and actions.
 	 *
-	 * @uses bp_Component::setup_actions() Setup the hooks and actions
+	 * @param string $id Unique ID (for internal identification). Letters,
+	 *        numbers, and underscores only.
+	 * @param string $name Unique name. This should be a translatable name,
+	 *        eg __( 'Groups', 'buddypress' ).
+	 * @param string $path The file path for the component's files. Used by
+	 *        {@link BP_Component::includes()}.
+	 * @param array $params Additional parameters used by the component.
+	 *        The config array supports the following values:
+	 *        - 'adminbar_myaccount_order' Sets the position for our
+	 *          component menu under the WP Toolbar's "My Account" menu.
 	 */
-	public function start( $id = '', $name = '', $path = '' ) {
+	public function start( $id = '', $name = '', $path = '', $params = array() ) {
 
 		// Internal identifier of component
 		$this->id   = $id;
@@ -107,31 +156,70 @@ class BP_Component {
 		// Path for includes
 		$this->path = $path;
 
+		// Miscellaneous component parameters that need to be set early on
+		if ( ! empty( $params ) ) {
+			// Sets the position for our menu under the WP Toolbar's "My Account" menu
+			if ( ! empty( $params['adminbar_myaccount_order'] ) ) {
+				$this->adminbar_myaccount_order = (int) $params['adminbar_myaccount_order'];
+			}
+
+		// Set defaults if not passed
+		} else {
+			// new component menus are added before the settings menu if not set
+			$this->adminbar_myaccount_order = 90;
+		}
+
 		// Move on to the next step
 		$this->setup_actions();
 	}
 
 	/**
-	 * Component global variables
+	 * Set up component global variables.
 	 *
 	 * @since BuddyPress (1.5)
 	 *
-	 * @uses apply_filters() Calls 'bp_{@link bp_Component::name}_id'
-	 * @uses apply_filters() Calls 'bp_{@link bp_Component::name}_slug'
+	 * @uses apply_filters() Calls 'bp_{@link bp_Component::name}_id'.
+	 * @uses apply_filters() Calls 'bp_{@link bp_Component::name}_slug'.
 	 *
-	 * @param array $args Optional
+	 * @param array $args {
+	 *     All values are optional.
+	 *     @type string $slug The component slug. Used to construct certain
+	 *           URLs, such as 'friends' in http://example.com/members/joe/friends/
+	 *           Default: the value of $this->id.
+	 *     @type string $root_slug The component root slug. Note that this
+	 *           value is generally unused if the component has a root
+	 *           directory (the slug will be overridden by the post_name of
+	 *           the directory page). Default: the slug of the directory
+	 *           page if one is found, otherwise an empty string.
+	 *     @type bool $has_directory Set to true if the component requires
+	 *           an associated WordPress page.
+	 *     @type callable $notification_callback Optional. The callable
+	 *           function that formats the component's notifications.
+	 *     @type string $search_term Optional. The placeholder text in the
+	 *           component directory search box. Eg, 'Search Groups...'.
+	 *     @type array $global_tables Optional. An array of database table
+	 *           names.
+	 *     @type array $meta_tables Optional. An array of metadata table
+	 *           names.
+	 * }
 	 */
 	public function setup_globals( $args = array() ) {
 
 		/** Slugs *************************************************************/
 
+		// If a WP directory page exists for the component, it should
+		// be the default value of 'root_slug'.
+		$default_root_slug = isset( buddypress()->pages->{$this->id}->slug ) ? buddypress()->pages->{$this->id}->slug : '';
+
 		$r = wp_parse_args( $args, array(
 			'slug'                  => $this->id,
-			'root_slug'             => '',
+			'root_slug'             => $default_root_slug,
 			'has_directory'         => false,
+			'directory_title'       => '',
 			'notification_callback' => '',
 			'search_string'         => '',
-			'global_tables'         => ''
+			'global_tables'         => '',
+			'meta_tables'           => '',
 		) );
 
 		// Slug used for permalink URI chunk after root
@@ -143,22 +231,23 @@ class BP_Component {
 		// Does this component have a top-level directory?
 		$this->has_directory         = apply_filters( 'bp_' . $this->id . '_has_directory',         $r['has_directory']         );
 
+		// Does this component have a top-level directory?
+		$this->directory_title       = apply_filters( 'bp_' . $this->id . '_directory_title',       $r['directory_title']         );
+
 		// Search string
 		$this->search_string         = apply_filters( 'bp_' . $this->id . '_search_string',         $r['search_string']         );
 
 		// Notifications callback
 		$this->notification_callback = apply_filters( 'bp_' . $this->id . '_notification_callback', $r['notification_callback'] );
 
-		// Set up global table names
-		if ( !empty( $r['global_tables'] ) ) {
-
-			// This filter allows for component-specific filtering of table names
-			// To filter *all* tables, use the 'bp_core_get_table_prefix' filter instead
-			$r['global_tables'] = apply_filters( 'bp_' . $this->id . '_global_tables', $r['global_tables'] );
+		// Set the global table names, if applicable
+		if ( ! empty( $r['global_tables'] ) ) {
+			$this->register_global_tables( $r['global_tables'] );
+		}
 
-			foreach ( $r['global_tables'] as $global_name => $table_name ) {
-				$this->$global_name = $table_name;
-			}
+		// Set the metadata table, if applicable
+		if ( ! empty( $r['meta_tables'] ) ) {
+			$this->register_meta_tables( $r['meta_tables'] );
 		}
 
 		/** BuddyPress ********************************************************/
@@ -171,28 +260,34 @@ class BP_Component {
 	}
 
 	/**
-	 * Include required files
+	 * Include required files.
 	 *
-	 * Please note that, by default, this method is fired on the bp_include hook, with priority
-	 * 8. This is necessary so that core components are loaded in time to be available to
-	 * third-party plugins. However, this load order means that third-party plugins whose main
-	 * files are loaded at bp_include with priority 10 (as recommended), will not be loaded in
-	 * time for their includes() method to fire automatically.
+	 * Please note that, by default, this method is fired on the bp_include
+	 * hook, with priority 8. This is necessary so that core components are
+	 * loaded in time to be available to third-party plugins. However, this
+	 * load order means that third-party plugins whose main files are
+	 * loaded at bp_include with priority 10 (as recommended), will not be
+	 * loaded in time for their includes() method to fire automatically.
 	 *
-	 * For this reason, it is recommended that your plugin has its own method or function for
-	 * requiring necessary files. If you must use this method, you will have to call it manually
-	 * in your constructor class, ie
+	 * For this reason, it is recommended that your plugin has its own
+	 * method or function for requiring necessary files. If you must use
+	 * this method, you will have to call it manually in your constructor
+	 * class, ie
 	 *   $this->includes();
 	 *
-	 * Note that when you pass an array value like 'actions' to includes, it looks for the
-	 * following three files (assuming your component is called 'my_component'):
+	 * Note that when you pass an array value like 'actions' to includes,
+	 * it looks for the following three files (assuming your component is
+	 * called 'my_component'):
 	 *   - ./actions
 	 *   - ./bp-my_component/actions
 	 *   - ./bp-my_component/bp-my_component-actions.php
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @uses do_action() Calls 'bp_{@link bp_Component::name}includes'
+	 * @uses do_action() Calls 'bp_{@link bp_Component::name}includes'.
+	 *
+	 * @param array $includes An array of file names, or file name chunks,
+	 *        to be parsed and then included.
 	 */
 	public function includes( $includes = array() ) {
 
@@ -221,7 +316,7 @@ class BP_Component {
 			foreach ( $paths as $path ) {
 				if ( @is_file( $slashed_path . $path ) ) {
 					require( $slashed_path . $path );
-					continue;
+					break;
 				}
 			}
 		}
@@ -231,12 +326,12 @@ class BP_Component {
 	}
 
 	/**
-	 * Setup the actions
+	 * Set up the actions.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @uses add_action() To add various actions
-	 * @uses do_action() Calls 'bp_{@link BP_Component::name}setup_actions'
+	 * @uses add_action() To add various actions.
+	 * @uses do_action() Calls 'bp_{@link BP_Component::name}setup_actions'.
 	 */
 	public function setup_actions() {
 
@@ -254,7 +349,7 @@ class BP_Component {
 		add_action( 'bp_setup_nav',              array( $this, 'setup_nav'              ), 10 );
 
 		// Setup WP Toolbar menus
-		add_action( 'bp_setup_admin_bar',        array( $this, 'setup_admin_bar'        ), 10 );
+		add_action( 'bp_setup_admin_bar',        array( $this, 'setup_admin_bar'        ), $this->adminbar_myaccount_order );
 
 		// Setup component title
 		add_action( 'bp_setup_title',            array( $this, 'setup_title'            ), 10 );
@@ -268,6 +363,15 @@ class BP_Component {
 		// Add the rewrite tags
 		add_action( 'bp_add_rewrite_tags',       array( $this, 'add_rewrite_tags'       ), 10 );
 
+		// Add the rewrite rules
+		add_action( 'bp_add_rewrite_rules',      array( $this, 'add_rewrite_rules'      ), 10 );
+
+		// Add the permalink structure
+		add_action( 'bp_add_permastructs',       array( $this, 'add_permastructs'       ), 10 );
+
+		// Allow components to parse the main query
+		add_action( 'bp_parse_query',            array( $this, 'parse_query'            ), 10 );
+
 		// Generate rewrite rules
 		add_action( 'bp_generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ), 10 );
 
@@ -276,10 +380,18 @@ class BP_Component {
 	}
 
 	/**
-	 * Setup the navigation
+	 * Set up component navigation.
+	 *
+	 * @see bp_core_new_nav_item() For a description of the $main_nav
+	 *      parameter formatting.
+	 * @see bp_core_new_subnav_item() For a description of how each item
+	 *      in the $sub_nav parameter array should be formatted.
 	 *
-	 * @param array $main_nav Optional
-	 * @param array $sub_nav Optional
+	 * @param array $main_nav Optional. Passed directly to
+	 *        bp_core_new_nav_item(). See that function for a description.
+	 * @param array $sub_nav Optional. Multidimensional array, each item in
+	 *        which is passed to bp_core_new_subnav_item(). See that
+	 *        function for a description.
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
 
@@ -300,10 +412,16 @@ class BP_Component {
 	}
 
 	/**
-	 * Setup the Toolbar
+	 * Set up the component entries in the WordPress Admin Bar.
 	 *
+	 * @see WP_Admin_Bar::add_menu() for a description of the syntax
+	 *      required by each item in the $wp_admin_nav parameter array.
 	 * @global obj $wp_admin_bar
-	 * @param array $wp_admin_menus
+	 *
+	 * @param array $wp_admin_nav An array of nav item arguments. Each item
+	 *        in this parameter array is passed to {@link WP_Admin_Bar::add_menu()}.
+	 *        See that method for a description of the required syntax for
+	 *        each item.
 	 */
 	public function setup_admin_bar( $wp_admin_nav = array() ) {
 
@@ -315,6 +433,9 @@ class BP_Component {
 		if ( !bp_use_wp_admin_bar() )
 			return;
 
+		// Filter the passed admin nav
+		$wp_admin_nav = apply_filters( 'bp_' . $this->id . '_admin_nav', $wp_admin_nav );
+
 		// Do we have Toolbar menus to add?
 		if ( !empty( $wp_admin_nav ) ) {
 
@@ -335,49 +456,142 @@ class BP_Component {
 	}
 
 	/**
-	 * Setup the component title
+	 * Set up the component title.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @uses do_action() Calls 'bp_{@link bp_Component::name}setup_title'
+	 * @uses do_action() Calls 'bp_{@link bp_Component::name}setup_title'.
 	 */
 	public function setup_title() {
 		do_action(  'bp_' . $this->id . '_setup_title' );
 	}
 
 	/**
-	 * Setup the component post types
+	 * Register global tables for the component, so that it may use WordPress's database API.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $tables
+	 */
+	public function register_global_tables( $tables = array() ) {
+
+		// This filter allows for component-specific filtering of table names
+		// To filter *all* tables, use the 'bp_core_get_table_prefix' filter instead
+		$tables = apply_filters( 'bp_' . $this->id . '_global_tables', $tables );
+
+		// Add to the BuddyPress global object
+		if ( !empty( $tables ) && is_array( $tables ) ) {
+			foreach ( $tables as $global_name => $table_name ) {
+				$this->$global_name = $table_name;
+			}
+
+			// Keep a record of the metadata tables in the component
+			$this->global_tables = $tables;
+		}
+
+		do_action( 'bp_' . $this->id . '_register_global_tables' );
+	}
+
+	/**
+	 * Register component metadata tables.
+	 *
+	 * Metadata tables are registered in the $wpdb global, for
+	 * compatibility with the WordPress metadata API.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $tables
+	 */
+	public function register_meta_tables( $tables = array() ) {
+		global $wpdb;
+
+		// This filter allows for component-specific filtering of table names
+		// To filter *all* tables, use the 'bp_core_get_table_prefix' filter instead
+		$tables = apply_filters( 'bp_' . $this->id . '_meta_tables', $tables );
+
+		/**
+		 * Add the name of each metadata table to WPDB to allow BuddyPress
+		 * components to play nicely with the WordPress metadata API.
+		 */
+		if ( !empty( $tables ) && is_array( $tables ) ) {
+			foreach( $tables as $meta_prefix => $table_name ) {
+				$wpdb->{$meta_prefix . 'meta'} = $table_name;
+			}
+
+			// Keep a record of the metadata tables in the component
+			$this->meta_tables = $tables;
+		}
+
+		do_action( 'bp_' . $this->id . '_register_meta_tables' );
+	}
+
+	/**
+	 * Set up the component post types.
+	 *
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_post_types'
+	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_post_types'.
 	 */
 	public function register_post_types() {
 		do_action( 'bp_' . $this->id . '_register_post_types' );
 	}
 
 	/**
-	 * Register component specific taxonomies
+	 * Register component-specific taxonomies.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_taxonomies'
+	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_taxonomies'.
 	 */
 	public function register_taxonomies() {
 		do_action( 'bp_' . $this->id . '_register_taxonomies' );
 	}
 
 	/**
-	 * Add any additional rewrite tags
+	 * Add any additional rewrite tags.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_rewrite_tags'
+	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_rewrite_tags'.
 	 */
 	public function add_rewrite_tags() {
 		do_action( 'bp_' . $this->id . '_add_rewrite_tags' );
 	}
 
+	/**
+	 * Add any additional rewrite rules.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_rewrite_rules'.
+	 */
+	public function add_rewrite_rules() {
+		do_action( 'bp_' . $this->id . '_add_rewrite_rules' );
+	}
+
+	/**
+	 * Add any permalink structures
+	 *
+	 * @since BuddyPress (1.9)
+	 *
+	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_permastruct'
+	 */
+	public function add_permastructs() {
+		do_action( 'bp_' . $this->id . '_add_permastructs' );
+	}
+
+	/**
+	 * Allow components to parse the main query
+	 *
+	 * @since BuddyPress (1.9)
+	 *
+	 * @uses do_action() Calls 'bp_{@link bp_Component::name}_parse_query'
+	 * @param object The main WP_Query
+	 */
+	public function parse_query( $query ) {
+		do_action_ref_array( 'bp_' . $this->id . '_parse_query', array( &$query ) );
+	}
+
 	/**
 	 * Generate any additional rewrite rules
 	 *
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-cssjs.php b/wp-content/plugins/buddypress/bp-core/bp-core-cssjs.php
index ff9608ac4993247378ef78a41600436c2e31b1d9..7a816a720a41afecbbac403c5d34e67ea7057ebe 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-cssjs.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-cssjs.php
@@ -1,39 +1,35 @@
 <?php
+/**
+ * Core component CSS & JS.
+ *
+ * @package BuddyPress
+ * @subpackage Core
+ */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Load the JS for "Are you sure?" .confirm links.
+ */
 function bp_core_confirmation_js() {
-
-	if ( is_multisite() && ! bp_is_root_blog() )
+	if ( is_multisite() && ! bp_is_root_blog() ) {
 		return false;
+	}
 
-	if ( !wp_script_is( 'jquery' ) )
-		wp_enqueue_script( 'jquery' );
-
-	if ( !wp_script_is( 'jquery', 'done' ) )
-		wp_print_scripts( 'jquery' ); ?>
+	$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
+	wp_enqueue_script( 'bp-confirm', buddypress()->plugin_url . "bp-core/js/confirm{$min}.js", array( 'jquery' ), bp_get_version() );
 
-	<script type="text/javascript">
-		jQuery( document ).ready( function() {
-			jQuery( 'a.confirm').click( function() {
-				if ( confirm( '<?php _e( 'Are you sure?', 'buddypress' ) ?>' ) )
-					return true; else return false;
-			});
-		});
-	</script>
+	wp_localize_script( 'bp-confirm', 'BP_Confirm', array(
+		'are_you_sure' => __( 'Are you sure?', 'buddypress' ),
+	) );
 
-<?php
 }
-add_action( 'wp_head',    'bp_core_confirmation_js', 100 );
-add_action( 'admin_head', 'bp_core_confirmation_js', 100 );
+add_action( 'wp_enqueue_scripts',    'bp_core_confirmation_js' );
+add_action( 'admin_enqueue_scripts', 'bp_core_confirmation_js' );
 
 /**
- * bp_core_add_jquery_cropper()
- *
- * Makes sure the jQuery jCrop library is loaded.
- *
- * @package BuddyPress Core
+ * Enqueues jCrop library and hooks BP's custom cropper JS.
  */
 function bp_core_add_jquery_cropper() {
 	wp_enqueue_style( 'jcrop' );
@@ -43,11 +39,7 @@ function bp_core_add_jquery_cropper() {
 }
 
 /**
- * bp_core_add_cropper_inline_js()
- *
- * Adds the inline JS needed for the cropper to work on a per-page basis.
- *
- * @package BuddyPress Core
+ * Output the inline JS needed for the cropper to work on a per-page basis.
  */
 function bp_core_add_cropper_inline_js() {
 
@@ -68,8 +60,8 @@ function bp_core_add_cropper_inline_js() {
 	}
 
 	// Default cropper coordinates
-	$crop_left   = $image[0] / 4;
-	$crop_top    = $image[1] / 4;
+	$crop_left   = round( $image[0] / 4 );
+	$crop_top    = round( $image[1] / 4 );
 	$crop_right  = $image[0] - $crop_left;
 	$crop_bottom = $image[1] - $crop_top; ?>
 
@@ -113,9 +105,7 @@ function bp_core_add_cropper_inline_js() {
 }
 
 /**
- * bp_core_add_cropper_inline_css()
- *
- * Adds the inline CSS needed for the cropper to work on a per-page basis.
+ * Output the inline CSS for the BP image cropper.
  *
  * @package BuddyPress Core
  */
@@ -137,9 +127,9 @@ function bp_core_add_cropper_inline_css() {
 }
 
 /**
- * Adds AJAX target URL so themes can access the WordPress AJAX functionality.
+ * Define the 'ajaxurl' JS variable, used by themes as an AJAX endpoint.
  *
- * @since BuddyPress (1.1)
+ * @since BuddyPress (1.1.0)
  */
 function bp_core_add_ajax_url_js() {
 ?>
@@ -151,14 +141,14 @@ function bp_core_add_ajax_url_js() {
 add_action( 'wp_head', 'bp_core_add_ajax_url_js' );
 
 /**
- * Returns the proper value for BP's ajaxurl
+ * Get the proper value for BP's ajaxurl.
  *
  * Designed to be sensitive to FORCE_SSL_ADMIN and non-standard multisite
  * configurations.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @return string
+ * @return string AJAX endpoint URL.
  */
 function bp_core_ajax_url() {
 	return apply_filters( 'bp_core_ajax_url', admin_url( 'admin-ajax.php', is_ssl() ? 'admin' : 'http' ) );
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-dependency.php b/wp-content/plugins/buddypress/bp-core/bp-core-dependency.php
index 59ed95fb31030d4148c6bcb0d7c17aca876aa107..eaf839c704204620f237ebb8f3c2e3de1ccc1bbe 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-dependency.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-dependency.php
@@ -1,52 +1,52 @@
 <?php
 
 /**
- * Plugin Dependency
+ * Plugin Dependency Action Hooks.
  *
  * The purpose of the following hooks is to mimic the behavior of something
  * called 'plugin dependency' which enables a plugin to have plugins of their
  * own in a safe and reliable way.
  *
- * We do this in BuddyPress by mirroring existing WordPress hookss in many places
+ * We do this in BuddyPress by mirroring existing WordPress hooks in many places
  * allowing dependant plugins to hook into the BuddyPress specific ones, thus
  * guaranteeing proper code execution only when BuddyPress is active.
  *
- * The following functions are wrappers for hookss, allowing them to be
+ * The following functions are wrappers for hooks, allowing them to be
  * manually called and/or piggy-backed on top of other hooks if needed.
  *
  * @todo use anonymous functions when PHP minimun requirement allows (5.3)
  */
 
 /**
- * Include files on this action
+ * Fire the 'bp_include' action, where plugins should include files.
  */
 function bp_include() {
 	do_action( 'bp_include' );
 }
 
 /**
- * Include files on this action
+ * Fire the 'bp_setup_components' action, where plugins should initialize components.
  */
 function bp_setup_components() {
 	do_action( 'bp_setup_components' );
 }
 
 /**
- * Setup global variables and objects
+ * Fire the 'bp_setup_globals' action, where plugins should initialize global settings.
  */
 function bp_setup_globals() {
 	do_action( 'bp_setup_globals' );
 }
 
 /**
- * Set navigation elements
+ * Fire the 'bp_setup_nav' action, where plugins should register their navigation items.
  */
 function bp_setup_nav() {
 	do_action( 'bp_setup_nav' );
 }
 
 /**
- * Set up BuddyPress implementation of the WP Toolbar
+ * Fire the 'bp_setup_admin_bar' action, where plugins should add items to the WP admin bar.
  */
 function bp_setup_admin_bar() {
 	if ( bp_use_wp_admin_bar() )
@@ -54,24 +54,24 @@ function bp_setup_admin_bar() {
 }
 
 /**
- * Set the page title
+ * Fire the 'bp_setup_title' action, where plugins should modify the page title.
  */
 function bp_setup_title() {
 	do_action( 'bp_setup_title' );
 }
 
 /**
- * Register widgets
+ * Fire the 'bp_register_widgets' action, where plugins should register widgets.
  */
 function bp_setup_widgets() {
 	do_action( 'bp_register_widgets' );
 }
 
 /**
- * Setup the currently logged-in user
+ * Set up the currently logged-in user.
  *
- * @uses did_action() To make sure the user isn't loaded out of order
- * @uses do_action() Calls 'bp_setup_current_user'
+ * @uses did_action() To make sure the user isn't loaded out of order.
+ * @uses do_action() Calls 'bp_setup_current_user'.
  */
 function bp_setup_current_user() {
 
@@ -85,49 +85,63 @@ function bp_setup_current_user() {
 }
 
 /**
- * Initlialize code
+ * Fire the 'bp_init' action, BuddyPress's main initialization hook.
  */
 function bp_init() {
 	do_action( 'bp_init' );
 }
 
 /**
- * Attached to plugins_loaded
+ * Fire the 'bp_loaded' action, which fires after BP's core plugin files have been loaded.
+ *
+ * Attached to 'plugins_loaded'.
  */
 function bp_loaded() {
 	do_action( 'bp_loaded' );
 }
 
 /**
- * Attached to wp
+ * Fire the 'bp_ready' action, which runs after BP is set up and the page is about to render.
+ *
+ * Attached to 'wp'.
  */
 function bp_ready() {
 	do_action( 'bp_ready' );
 }
 
 /**
- * Attach potential template actions
+ * Fire the 'bp_actions' action, which runs just before rendering.
+ *
+ * Attach potential template actions, such as catching form requests or routing
+ * custom URLs.
  */
 function bp_actions() {
 	do_action( 'bp_actions' );
 }
 
 /**
- * Attach potential template screens
+ * Fire the 'bp_screens' action, which runs just before rendering.
+ *
+ * Runs just after 'bp_actions'. Use this hook to attach your template
+ * loaders.
  */
 function bp_screens() {
 	do_action( 'bp_screens' );
 }
 
 /**
- * Initialize widgets
+ * Fire 'bp_widgets_init', which runs after widgets have been set up.
+ *
+ * Hooked to 'widgets_init'.
  */
 function bp_widgets_init() {
 	do_action ( 'bp_widgets_init' );
 }
 
 /**
- * BuddyPress head scripts
+ * Fire 'bp_head', which is used to hook scripts and styles in the <head>.
+ *
+ * Hooked to 'wp_head'.
  */
 function bp_head() {
 	do_action ( 'bp_head' );
@@ -136,10 +150,13 @@ function bp_head() {
 /** Theme Permissions *********************************************************/
 
 /**
- * The main action used for redirecting BuddyPress theme actions that are not
- * permitted by the current_user
+ * Fire the 'bp_template_redirect' action.
+ *
+ * Run at 'template_redirect', just before WordPress selects and loads a theme
+ * template. The main purpose of this hook in BuddyPress is to redirect users
+ * who do not have the proper permission to access certain content.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
  * @uses do_action()
  */
@@ -150,9 +167,12 @@ function bp_template_redirect() {
 /** Theme Helpers *************************************************************/
 
 /**
- * The main action used registering theme directory
+ * Fire the 'bp_register_theme_directory' action.
+ *
+ * The main action used registering theme directories.
+ *
+ * @since BuddyPress (1.5.0)
  *
- * @since BuddyPress (1.5)
  * @uses do_action()
  */
 function bp_register_theme_directory() {
@@ -160,9 +180,12 @@ function bp_register_theme_directory() {
 }
 
 /**
- * The main action used registering theme packages
+ * Fire the 'bp_register_theme_packages' action.
+ *
+ * The main action used registering theme packages.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
  * @uses do_action()
  */
 function bp_register_theme_packages() {
@@ -170,49 +193,76 @@ function bp_register_theme_packages() {
 }
 
 /**
- * Enqueue BuddyPress specific CSS and JS
+ * Fire the 'bp_enqueue_scripts' action, where BP enqueues its CSS and JS.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @uses do_action() Calls 'bp_enqueue_scripts'
+ * @uses do_action() Calls 'bp_enqueue_scripts'.
  */
 function bp_enqueue_scripts() {
 	do_action ( 'bp_enqueue_scripts' );
 }
 
 /**
- * Add the BuddyPress-specific rewrite tags
+ * Fire the 'bp_add_rewrite_tag' action, where BP adds its custom rewrite tags.
  *
- * @since BuddyPress (1.8)
- * @uses do_action() Calls 'bp_add_rewrite_tags'
+ * @since BuddyPress (1.8.0)
+ *
+ * @uses do_action() Calls 'bp_add_rewrite_tags'.
  */
 function bp_add_rewrite_tags() {
 	do_action( 'bp_add_rewrite_tags' );
 }
 
 /**
- * Piggy back action for BuddyPress sepecific theme actions before the theme has
- * been setup and the theme's functions.php has loaded.
+ * Fire the 'bp_add_rewrite_rules' action, where BP adds its custom rewrite rules.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.9.0)
  *
- * @uses do_action() Calls 'bp_setup_theme'
+ * @uses do_action() Calls 'bp_add_rewrite_rules'.
+ */
+function bp_add_rewrite_rules() {
+	do_action( 'bp_add_rewrite_rules' );
+}
+
+/**
+ * Fire the 'bp_add_permastructs' action, where BP adds its BP-specific permalink structure.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @uses do_action() Calls 'bp_add_permastructs'.
+ */
+function bp_add_permastructs() {
+	do_action( 'bp_add_permastructs' );
+}
+
+/**
+ * Fire the 'bp_setup_theme' action.
+ *
+ * The main purpose of 'bp_setup_theme' is give themes a place to load their
+ * BuddyPress-specific functionality.
+ *
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses do_action() Calls 'bp_setup_theme'.
  */
 function bp_setup_theme() {
 	do_action ( 'bp_setup_theme' );
 }
 
 /**
- * Piggy back action for BuddyPress sepecific theme actions once the theme has
- * been setup and the theme's functions.php has loaded.
+ * Fire the 'bp_after_setup_theme' action.
+ *
+ * Piggy-back action for BuddyPress-specific theme actions once the theme has
+ * been set up and the theme's functions.php has loaded.
  *
  * Hooked to 'after_setup_theme' with a priority of 100. This allows plenty of
  * time for other themes to load their features, such as BuddyPress support,
  * before our theme compatibility layer kicks in.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @uses do_action() Calls 'bp_after_setup_theme'
+ * @uses do_action() Calls 'bp_after_setup_theme'.
  */
 function bp_after_setup_theme() {
 	do_action ( 'bp_after_setup_theme' );
@@ -221,61 +271,120 @@ function bp_after_setup_theme() {
 /** Theme Compatibility Filter ************************************************/
 
 /**
- * Piggy back filter for WordPress's 'request' filter
+ * Fire the 'bp_request' filter, a piggy-back of WP's 'request'.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
- * @param array $query_vars
- * @return array
+ * @see WP::parse_request() for a description of parameters.
+ *
+ * @param array $query_vars See {@link WP::parse_request()}.
+ * @return array $query_vars See {@link WP::parse_request()}.
  */
 function bp_request( $query_vars = array() ) {
 	return apply_filters( 'bp_request', $query_vars );
 }
 
 /**
- * Piggy back filter to handle login redirects.
+ * Fire the 'bp_login_redirect' filter, a piggy-back of WP's 'login_redirect'.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @param string $redirect_to
- * @param string $redirect_to_raw
- * @param string $user
+ * @param string $redirect_to See 'login_redirect'.
+ * @param string $redirect_to_raw See 'login_redirect'.
+ * @param string $user See 'login_redirect'.
  */
 function bp_login_redirect( $redirect_to = '', $redirect_to_raw = '', $user = false ) {
 	return apply_filters( 'bp_login_redirect', $redirect_to, $redirect_to_raw, $user );
 }
 
 /**
- * The main filter used for theme compatibility and displaying custom BuddyPress
- * theme files.
+ * Fire 'bp_template_include', main filter used for theme compatibility and displaying custom BP theme files.
+ *
+ * Hooked to 'template_include'.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
  * @uses apply_filters()
  *
- * @param string $template
- * @return string Template file to use
+ * @param string $template See 'template_include'.
+ * @return string Template file to use.
  */
 function bp_template_include( $template = '' ) {
 	return apply_filters( 'bp_template_include', $template );
 }
 
 /**
- * Generate BuddyPress-specific rewrite rules
+ * Fire the 'bp_generate_rewrite_rules' filter, where BP generates its rewrite rules.
+ *
+ * @since BuddyPress (1.7.0)
+ *
+ * @uses do_action() Calls 'bp_generate_rewrite_rules' with {@link WP_Rewrite}.
  *
- * @since BuddyPress (1.7)
- * @param WP_Rewrite $wp_rewrite
- * @uses do_action() Calls 'bp_generate_rewrite_rules' with {@link WP_Rewrite}
+ * @param WP_Rewrite $wp_rewrite See 'generate_rewrite_rules'.
  */
 function bp_generate_rewrite_rules( $wp_rewrite ) {
 	do_action_ref_array( 'bp_generate_rewrite_rules', array( &$wp_rewrite ) );
 }
 
 /**
- * Filter the allowed themes list for BuddyPress specific themes
+ * Fire the 'bp_allowed_themes' filter.
  *
- * @since BuddyPress (1.7)
- * @uses apply_filters() Calls 'bp_allowed_themes' with the allowed themes list
+ * Filter the allowed themes list for BuddyPress-specific themes.
+ *
+ * @since BuddyPress (1.7.0)
+ *
+ * @uses apply_filters() Calls 'bp_allowed_themes' with the allowed themes list.
  */
 function bp_allowed_themes( $themes ) {
 	return apply_filters( 'bp_allowed_themes', $themes );
 }
+
+/** Requests ******************************************************************/
+
+/**
+ * The main action used for handling theme-side POST requests
+ *
+ * @since BuddyPress (1.9.0)
+ * @uses do_action()
+ */
+function bp_post_request() {
+
+	// Bail if not a POST action
+	if ( ! bp_is_post_request() )
+		return;
+
+	// Bail if no action
+	if ( empty( $_POST['action'] ) )
+		return;
+
+	// This dynamic action is probably the one you want to use. It narrows down
+	// the scope of the 'action' without needing to check it in your function.
+	do_action( 'bp_post_request_' . $_POST['action'] );
+
+	// Use this static action if you don't mind checking the 'action' yourself.
+	do_action( 'bp_post_request',   $_POST['action'] );
+}
+
+/**
+ * The main action used for handling theme-side GET requests
+ *
+ * @since BuddyPress (1.9.0)
+ * @uses do_action()
+ */
+function bp_get_request() {
+
+	// Bail if not a POST action
+	if ( ! bp_is_get_request() )
+		return;
+
+	// Bail if no action
+	if ( empty( $_GET['action'] ) )
+		return;
+
+	// This dynamic action is probably the one you want to use. It narrows down
+	// the scope of the 'action' without needing to check it in your function.
+	do_action( 'bp_get_request_' . $_GET['action'] );
+
+	// Use this static action if you don't mind checking the 'action' yourself.
+	do_action( 'bp_get_request',   $_GET['action'] );
+}
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-filters.php b/wp-content/plugins/buddypress/bp-core/bp-core-filters.php
index ac2d1a1ba9f46f077d90aedf255f6d31276ee118..910e5a2f91a733c5ebca31093d27ab74ced7e8c0 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-filters.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-filters.php
@@ -1,16 +1,13 @@
 <?php
 
 /**
- * BuddyPress Filters
+ * BuddyPress Filters.
  *
- * @package BuddyPress
- * @subpackage Core
- *
- * This file contains the filters that are used through-out BuddyPress. They are
+ * This file contains the filters that are used throughout BuddyPress. They are
  * consolidated here to make searching for them easier, and to help developers
  * understand at a glance the order in which things occur.
  *
- * There are a few common places that additional filters can currently be found
+ * There are a few common places that additional filters can currently be found.
  *
  *  - BuddyPress: In {@link BuddyPress::setup_actions()} in buddypress.php
  *  - Component: In {@link BP_Component::setup_actions()} in
@@ -18,6 +15,8 @@
  *  - Admin: More in {@link BP_Admin::setup_actions()} in
  *            bp-core/bp-core-admin.php
  *
+ * @package BuddyPress
+ * @subpackage Core
  * @see bp-core-actions.php
  */
 
@@ -25,7 +24,7 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Attach BuddyPress to WordPress
+ * Attach BuddyPress to WordPress.
  *
  * BuddyPress uses its own internal actions to help aid in third-party plugin
  * development, and to limit the amount of potential future code changes when
@@ -54,7 +53,7 @@ add_filter( 'bp_core_render_message_content', 'shortcode_unautop' );
 add_filter( 'bp_core_render_message_content', 'wp_kses_data', 5   );
 
 /**
- * Template Compatibility
+ * Template Compatibility.
  *
  * If you want to completely bypass this and manage your own custom BuddyPress
  * template hierarchy, start here by removing this filter, then look at how
@@ -70,13 +69,13 @@ add_filter( 'bp_get_template_stack', 'bp_add_template_stack_locations'
 add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
 
 /**
- * bp_core_exclude_pages()
- *
- * Excludes specific pages from showing on page listings, for example the "Activation" page.
+ * Prevent specific pages (eg 'Activate') from showing on page listings.
  *
- * @package BuddyPress Core
  * @uses bp_is_active() checks if a BuddyPress component is active.
- * @return array The list of page ID's to exclude
+ *
+ * @param array $pages List of excluded page IDs, as passed to the
+ *        'wp_list_pages_excludes' filter.
+ * @return array The exclude list, with BP's pages added.
  */
 function bp_core_exclude_pages( $pages = array() ) {
 
@@ -100,13 +99,52 @@ function bp_core_exclude_pages( $pages = array() ) {
 add_filter( 'wp_list_pages_excludes', 'bp_core_exclude_pages' );
 
 /**
- * bp_core_email_from_name_filter()
+ * Prevent specific pages (eg 'Activate') from showing in the Pages meta box of the Menu Administration screen.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @uses bp_is_root_blog() checks if current blog is root blog.
+ * @uses buddypress() gets BuddyPress main instance
+ *
+ * @param object $object The post type object used in the meta box
+ * @return object The $object, with a query argument to remove register and activate pages id.
+ */
+function bp_core_exclude_pages_from_nav_menu_admin( $object = null ) {
+
+	// Bail if not the root blog
+	if ( ! bp_is_root_blog() ) {
+		return $object;
+	}
+
+	if ( 'page' != $object->name ) {
+		return $object;
+	}
+
+	$bp = buddypress();
+	$pages = array();
+
+	if ( ! empty( $bp->pages->activate ) ) {
+		$pages[] = $bp->pages->activate->id;
+	}
+
+	if ( ! empty( $bp->pages->register ) ) {
+		$pages[] = $bp->pages->register->id;
+	}
+
+	if ( ! empty( $pages ) ) {
+		$object->_default_query['post__not_in'] = $pages;
+	}
+
+	return $object;
+}
+add_filter( 'nav_menu_meta_box_object', 'bp_core_exclude_pages_from_nav_menu_admin', 11, 1 );
+
+/**
+ * Set "From" name in outgoing email to the site name.
  *
- * Sets the "From" name in emails sent to the name of the site and not "WordPress"
+ * @uses bp_get_option() fetches the value for a meta_key in the wp_X_options table.
  *
- * @package BuddyPress Core
- * @uses bp_get_option() fetches the value for a meta_key in the wp_X_options table
- * @return string The blog name for the root blog
+ * @return string The blog name for the root blog.
  */
 function bp_core_email_from_name_filter() {
  	return apply_filters( 'bp_core_email_from_name_filter', bp_get_option( 'blogname', 'WordPress' ) );
@@ -114,11 +152,11 @@ function bp_core_email_from_name_filter() {
 add_filter( 'wp_mail_from_name', 'bp_core_email_from_name_filter' );
 
 /**
- * bp_core_filter_comments()
- *
  * Filter the blog post comments array and insert BuddyPress URLs for users.
  *
- * @package BuddyPress Core
+ * @param array $comments The array of comments supplied to the comments template.
+ * @param int $post->ID The post ID.
+ * @return array $comments The modified comment array.
  */
 function bp_core_filter_comments( $comments, $post_id ) {
 	global $wpdb;
@@ -151,17 +189,17 @@ function bp_core_filter_comments( $comments, $post_id ) {
 add_filter( 'comments_array', 'bp_core_filter_comments', 10, 2 );
 
 /**
- * When a user logs in, redirect him in a logical way
+ * When a user logs in, redirect him in a logical way.
  *
- * @package BuddyPress Core
+ * @uses apply_filters() Filter 'bp_core_login_redirect' to modify where users
+ *       are redirected to on login.
  *
- * @uses apply_filters Filter bp_core_login_redirect to modify where users are redirected to on
- *   login
- * @param string $redirect_to The URL to be redirected to, sanitized in wp-login.php
+ * @param string $redirect_to The URL to be redirected to, sanitized
+ *        in wp-login.php.
  * @param string $redirect_to_raw The unsanitized redirect_to URL ($_REQUEST['redirect_to'])
- * @param WP_User $user The WP_User object corresponding to a successfully logged-in user. Otherwise
- *   a WP_Error object
- * @return string The redirect URL
+ * @param WP_User $user The WP_User object corresponding to a successfully
+ *        logged-in user. Otherwise a WP_Error object.
+ * @return string The redirect URL.
  */
 function bp_core_login_redirect( $redirect_to, $redirect_to_raw, $user ) {
 
@@ -192,22 +230,29 @@ function bp_core_login_redirect( $redirect_to, $redirect_to_raw, $user ) {
 		return wp_get_referer();
 	}
 
-	return bp_get_root_domain();
+	return apply_filters( 'bp_core_login_redirect_to', bp_get_root_domain() );
 }
 add_filter( 'bp_login_redirect', 'bp_core_login_redirect', 10, 3 );
 
-/***
- * bp_core_filter_user_welcome_email()
+/**
+ * Replace the generated password in the welcome email with '[User Set]'.
  *
- * Replace the generated password in the welcome email.
- * This will not filter when the site admin registers a user.
+ * On a standard BP installation, users who register themselves also set their
+ * own passwords. Therefore there is no need for the insecure practice of
+ * emailing the plaintext password to the user in the welcome email.
  *
- * @uses locate_template To see if custom registration files exist
- * @param string $welcome_email Complete email passed through WordPress
- * @return string Filtered $welcome_email with 'PASSWORD' replaced by [User Set]
+ * This filter will not fire when a user is registered by the site admin.
+ *
+ * @param string $welcome_email Complete email passed through WordPress.
+ * @return string Filtered $welcome_email with the password replaced
+ *         by '[User Set]'.
  */
 function bp_core_filter_user_welcome_email( $welcome_email ) {
 
+	// Don't touch the email when a user is registered by the site admin
+	if ( is_admin() )
+		return $welcome_email;
+
 	// Don't touch the email if we don't have a custom registration template
 	if ( ! bp_has_custom_signup_page() )
 		return $welcome_email;
@@ -217,21 +262,27 @@ function bp_core_filter_user_welcome_email( $welcome_email ) {
 }
 add_filter( 'update_welcome_user_email', 'bp_core_filter_user_welcome_email' );
 
-/***
- * bp_core_filter_blog_welcome_email()
+/**
+ * Replace the generated password in the welcome email with '[User Set]'.
+ *
+ * On a standard BP installation, users who register themselves also set their
+ * own passwords. Therefore there is no need for the insecure practice of
+ * emailing the plaintext password to the user in the welcome email.
  *
- * Replace the generated password in the welcome email.
- * This will not filter when the site admin registers a user.
+ * This filter will not fire when a user is registered by the site admin.
  *
- * @uses locate_template To see if custom registration files exist
- * @param string $welcome_email Complete email passed through WordPress
- * @param integer $blog_id ID of the blog user is joining
- * @param integer $user_id ID of the user joining
- * @param string $password Password of user
- * @return string Filtered $welcome_email with $password replaced by [User Set]
+ * @param string $welcome_email Complete email passed through WordPress.
+ * @param int $blog_id ID of the blog user is joining.
+ * @param int $user_id ID of the user joining.
+ * @param string $password Password of user.
+ * @return string Filtered $welcome_email with $password replaced by '[User Set]'.
  */
 function bp_core_filter_blog_welcome_email( $welcome_email, $blog_id, $user_id, $password ) {
 
+	// Don't touch the email when a user is registered by the site admin.
+	if ( is_admin() )
+		return $welcome_email;
+
 	// Don't touch the email if we don't have a custom registration template
 	if ( ! bp_has_custom_signup_page() )
 		return $welcome_email;
@@ -241,29 +292,44 @@ function bp_core_filter_blog_welcome_email( $welcome_email, $blog_id, $user_id,
 }
 add_filter( 'update_welcome_email', 'bp_core_filter_blog_welcome_email', 10, 4 );
 
-// Notify user of signup success.
+/**
+ * Notify new users of a successful registration (with blog).
+ *
+ * This function filter's WP's 'wpmu_signup_blog_notification', and replaces
+ * WP's default welcome email with a BuddyPress-specific message.
+ *
+ * @see wpmu_signup_blog_notification() for a description of parameters.
+ *
+ * @param string $domain The new blog domain.
+ * @param string $path The new blog path.
+ * @param string $title The site title.
+ * @param string $user The user's login name.
+ * @param string $user_email The user's email address.
+ * @param string $key The activation key created in wpmu_signup_blog()
+ * @param array $meta By default, contains the requested privacy setting and
+ *        lang_id.
+ * @return bool True on success, false on failure.
+ */
 function bp_core_activation_signup_blog_notification( $domain, $path, $title, $user, $user_email, $key, $meta ) {
 
-	// Send email with activation link.
+	// Set up activation link
 	$activate_url = bp_get_activation_page() ."?key=$key";
 	$activate_url = esc_url( $activate_url );
 
-	$admin_email = get_site_option( 'admin_email' );
-
-	if ( empty( $admin_email ) )
-		$admin_email = 'support@' . $_SERVER['SERVER_NAME'];
+	// Email contents
+	$message = sprintf( __( "Thanks for registering! To complete the activation of your account and blog, please click the following link:\n\n%1\$s\n\n\n\nAfter you activate, you can visit your blog here:\n\n%2\$s", 'buddypress' ), $activate_url, esc_url( "http://{$domain}{$path}" ) );
+	$subject = bp_get_email_subject( array( 'text' => sprintf( __( 'Activate %s', 'buddypress' ), 'http://' . $domain . $path ) ) );
 
-	$from_name       = bp_get_option( 'blogname', 'WordPress' );
-	$message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option( 'blog_charset' ) . "\"\n";
-	$message         = sprintf( __( "Thanks for registering! To complete the activation of your account and blog, please click the following link:\n\n%1\$s\n\n\n\nAfter you activate, you can visit your blog here:\n\n%2\$s", 'buddypress' ), $activate_url, esc_url( "http://{$domain}{$path}" ) );
-	$subject         = bp_get_email_subject( array( 'text' => sprintf( __( 'Activate %s', 'buddypress' ), 'http://' . $domain . $path ) ) );
+	// Email filters
+	$to      = apply_filters( 'bp_core_activation_signup_blog_notification_to',   $user_email, $domain, $path, $title, $user, $user_email, $key, $meta );
+	$subject = apply_filters( 'bp_core_activation_signup_blog_notification_subject', $subject, $domain, $path, $title, $user, $user_email, $key, $meta );
+	$message = apply_filters( 'bp_core_activation_signup_blog_notification_message', $message, $domain, $path, $title, $user, $user_email, $key, $meta );
 
-	// Send the message
-	$to              = apply_filters( 'bp_core_activation_signup_blog_notification_to',   $user_email, $domain, $path, $title, $user, $user_email, $key, $meta );
-	$subject         = apply_filters( 'bp_core_activation_signup_blog_notification_subject', $subject, $domain, $path, $title, $user, $user_email, $key, $meta );
-	$message         = apply_filters( 'bp_core_activation_signup_blog_notification_message', $message, $domain, $path, $title, $user, $user_email, $key, $meta );
+	// Send the email
+	wp_mail( $to, $subject, $message );
 
-	wp_mail( $to, $subject, $message, $message_headers );
+	// Set up the $admin_email to pass to the filter
+	$admin_email = bp_get_option( 'admin_email' );
 
 	do_action( 'bp_core_sent_blog_signup_email', $admin_email, $subject, $message, $domain, $path, $title, $user, $user_email, $key, $meta );
 
@@ -272,26 +338,37 @@ function bp_core_activation_signup_blog_notification( $domain, $path, $title, $u
 }
 add_filter( 'wpmu_signup_blog_notification', 'bp_core_activation_signup_blog_notification', 1, 7 );
 
+/**
+ * Notify new users of a successful registration (without blog).
+ *
+ * @see wpmu_signup_user_notification() for a full description of params.
+ *
+ * @param string $user The user's login name.
+ * @param string $user_email The user's email address.
+ * @param string $key The activation key created in wpmu_signup_user()
+ * @param array $meta By default, an empty array.
+ * @return bool True on success, false on failure.
+ */
 function bp_core_activation_signup_user_notification( $user, $user_email, $key, $meta ) {
 
+	// Set up activation link
 	$activate_url = bp_get_activation_page() . "?key=$key";
-	$activate_url = esc_url($activate_url);
-	$admin_email  = get_site_option( 'admin_email' );
-
-	if ( empty( $admin_email ) )
-		$admin_email = 'support@' . $_SERVER['SERVER_NAME'];
+	$activate_url = esc_url( $activate_url );
 
-	$from_name       = bp_get_option( 'blogname', 'WordPress' );
-	$message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option( 'blog_charset' ) . "\"\n";
-	$message         = sprintf( __( "Thanks for registering! To complete the activation of your account please click the following link:\n\n%1\$s\n\n", 'buddypress' ), $activate_url );
-	$subject         = bp_get_email_subject( array( 'text' => __( 'Activate Your Account', 'buddypress' ) ) );
+	// Email contents
+	$message = sprintf( __( "Thanks for registering! To complete the activation of your account please click the following link:\n\n%1\$s\n\n", 'buddypress' ), $activate_url );
+	$subject = bp_get_email_subject( array( 'text' => __( 'Activate Your Account', 'buddypress' ) ) );
 
-	// Send the message
+	// Email filters
 	$to      = apply_filters( 'bp_core_activation_signup_user_notification_to',   $user_email, $user, $user_email, $key, $meta );
 	$subject = apply_filters( 'bp_core_activation_signup_user_notification_subject', $subject, $user, $user_email, $key, $meta );
 	$message = apply_filters( 'bp_core_activation_signup_user_notification_message', $message, $user, $user_email, $key, $meta );
 
-	wp_mail( $to, $subject, $message, $message_headers );
+	// Send the email
+	wp_mail( $to, $subject, $message );
+
+	// Set up the $admin_email to pass to the filter
+	$admin_email = bp_get_option( 'admin_email' );
 
 	do_action( 'bp_core_sent_user_signup_email', $admin_email, $subject, $message, $user, $user_email, $key, $meta );
 
@@ -301,15 +378,17 @@ function bp_core_activation_signup_user_notification( $user, $user_email, $key,
 add_filter( 'wpmu_signup_user_notification', 'bp_core_activation_signup_user_notification', 1, 4 );
 
 /**
- * Filter the page title for BuddyPress pages
+ * Filter the page title for BuddyPress pages.
+ *
+ * @since BuddyPress (1.5.0)
  *
- * @global object $bp BuddyPress global settings
- * @param string $title Original page title
- * @param string $sep How to separate the various items within the page title.
- * @param string $seplocation Direction to display title
- * @return string new page title
  * @see wp_title()
- * @since BuddyPress (1.5)
+ * @global object $bp BuddyPress global settings.
+ *
+ * @param string $title Original page title.
+ * @param string $sep How to separate the various items within the page title.
+ * @param string $seplocation Direction to display title.
+ * @return string New page title.
  */
 function bp_modify_page_title( $title, $sep, $seplocation ) {
 	global $bp;
@@ -318,6 +397,11 @@ function bp_modify_page_title( $title, $sep, $seplocation ) {
 	if ( bp_is_blog_page() )
 		return $title;
 
+	// If this is a 404, let WordPress handle it
+	if ( is_404() ) {
+		return $title;
+	}
+
 	// If this is the front page of the site, return WP's title
 	if ( is_front_page() || is_home() )
 		return $title;
@@ -355,10 +439,14 @@ function bp_modify_page_title( $title, $sep, $seplocation ) {
 
 	// An index or directory
 	} elseif ( bp_is_directory() ) {
-		if ( !bp_current_component() ) {
-			$title = sprintf( __( '%s Directory', 'buddypress' ), bp_get_name_from_root_slug() );
+
+		$current_component = bp_current_component();
+
+		// No current component (when does this happen?)
+		if ( empty( $current_component ) ) {
+			$title = _x( 'Directory', 'component directory title', 'buddypress' );
 		} else {
-			$title = sprintf( __( '%s Directory', 'buddypress' ), bp_get_name_from_root_slug() );
+			$title = bp_get_directory_title( $current_component );
 		}
 
 	// Sign up page
@@ -387,3 +475,94 @@ add_filter( 'wp_title', 'bp_modify_page_title', 10, 3 );
 add_filter( 'bp_modify_page_title', 'wptexturize'     );
 add_filter( 'bp_modify_page_title', 'convert_chars'   );
 add_filter( 'bp_modify_page_title', 'esc_html'        );
+
+/**
+ * Add BuddyPress-specific items to the wp_nav_menu.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param WP_Post $menu_item The menu item.
+ * @return obj The modified WP_Post object.
+ */
+function bp_setup_nav_menu_item( $menu_item ) {
+	if ( is_admin() ) {
+		return $menu_item;
+	}
+
+	// We use information stored in the CSS class to determine what kind of
+	// menu item this is, and how it should be treated
+	$css_target = preg_match( '/\sbp-(.*)-nav/', implode( ' ', $menu_item->classes), $matches );
+
+	// If this isn't a BP menu item, we can stop here
+	if ( empty( $matches[1] ) ) {
+		return $menu_item;
+	}
+
+	switch ( $matches[1] ) {
+		case 'login' :
+			if ( is_user_logged_in() ) {
+				$menu_item->_invalid = true;
+			} else {
+				$menu_item->url = wp_login_url( wp_guess_url() );
+			}
+
+			break;
+
+		case 'logout' :
+			if ( ! is_user_logged_in() ) {
+				$menu_item->_invalid = true;
+			} else {
+				$menu_item->url = wp_logout_url( wp_guess_url() );
+			}
+
+			break;
+
+		// Don't show the Register link to logged-in users
+		case 'register' :
+			if ( is_user_logged_in() ) {
+				$menu_item->_invalid = true;
+			}
+
+			break;
+
+		// All other BP nav items are specific to the logged-in user,
+		// and so are not relevant to logged-out users
+		default:
+			if ( is_user_logged_in() ) {
+				$menu_item->url = bp_nav_menu_get_item_url( $matches[1] );
+			} else {
+				$menu_item->_invalid = true;
+			}
+
+			break;
+	}
+
+	// Highlight the current page
+	$current = bp_get_requested_url();
+	if ( strpos( $current, $menu_item->url ) !== false ) {
+		$menu_item->classes[] = 'current_page_item';
+	}
+
+	return $menu_item;
+}
+add_filter( 'wp_setup_nav_menu_item', 'bp_setup_nav_menu_item', 10, 1 );
+
+/**
+ * Filter SQL query strings to swap out the 'meta_id' column.
+ *
+ * WordPress uses the meta_id column for commentmeta and postmeta, and so
+ * hardcodes the column name into its *_metadata() functions. BuddyPress, on
+ * the other hand, uses 'id' for the primary column. To make WP's functions
+ * usable for BuddyPress, we use this just-in-time filter on 'query' to swap
+ * 'meta_id' with 'id.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @access private Do not use.
+ *
+ * @param string $q SQL query.
+ * @return string
+ */
+function bp_filter_metaid_column_name( $q ) {
+	return str_replace( 'meta_id', 'id', $q );
+}
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-functions.php b/wp-content/plugins/buddypress/bp-core/bp-core-functions.php
index 91df205d50ddf90e589c6b4d0d176282d63602ea..438e396b54a6a526b5e4459053aa4940f9407cd2 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-functions.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-functions.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Common Functions
+ * BuddyPress Common Functions.
  *
  * @package BuddyPress
  * @subpackage Functions
@@ -13,48 +13,52 @@ if ( !defined( 'ABSPATH' ) ) exit;
 /** Versions ******************************************************************/
 
 /**
- * Output the BuddyPress version
+ * Output the BuddyPress version.
  *
- * @since BuddyPress (1.6)
- * @uses bp_get_version() To get the BuddyPress version
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses bp_get_version() To get the BuddyPress version.
  */
 function bp_version() {
 	echo bp_get_version();
 }
 	/**
-	 * Return the BuddyPress version
+	 * Return the BuddyPress version.
 	 *
-	 * @since BuddyPress (1.6)
-	 * @return string The BuddyPress version
+	 * @since BuddyPress (1.6.0)
+	 *
+	 * @return string The BuddyPress version.
 	 */
 	function bp_get_version() {
 		return buddypress()->version;
 	}
 
 /**
- * Output the BuddyPress database version
+ * Output the BuddyPress database version.
  *
- * @since BuddyPress (1.6)
- * @uses bp_get_db_version() To get the BuddyPress version
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses bp_get_db_version() To get the BuddyPress database version.
  */
 function bp_db_version() {
 	echo bp_get_db_version();
 }
 	/**
-	 * Return the BuddyPress database version
+	 * Return the BuddyPress database version.
 	 *
-	 * @since BuddyPress (1.6)
-	 * @return string The BuddyPress version
+	 * @since BuddyPress (1.6.0)
+	 * @return string The BuddyPress database version.
 	 */
 	function bp_get_db_version() {
 		return buddypress()->db_version;
 	}
 
 /**
- * Output the BuddyPress database version
+ * Output the BuddyPress database version.
  *
- * @since BuddyPress (1.6)
- * @uses bp_get_db_version_raw() To get the current BuddyPress version
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses bp_get_db_version_raw() To get the current database BuddyPress version.
  */
 function bp_db_version_raw() {
 	echo bp_get_db_version_raw();
@@ -63,7 +67,8 @@ function bp_db_version_raw() {
 	 * Return the BuddyPress database version
 	 *
 	 * @since BuddyPress (1.6)
-	 * @return string The BuddyPress version direct from the database
+	 *
+	 * @return string The BuddyPress version direct from the database.
 	 */
 	function bp_get_db_version_raw() {
 		$bp     = buddypress();
@@ -73,10 +78,13 @@ function bp_db_version_raw() {
 /** Functions *****************************************************************/
 
 /**
- * Allow filtering of database prefix. Intended for use in multinetwork installations.
+ * Get the $wpdb base prefix, run through the 'bp_core_get_table_prefix' filter.
+ *
+ * The filter is intended primarily for use in multinetwork installations.
  *
- * @global object $wpdb WordPress database object
- * @return string Filtered database prefix
+ * @global object $wpdb WordPress database object.
+ *
+ * @return string Filtered database prefix.
  */
 function bp_core_get_table_prefix() {
 	global $wpdb;
@@ -85,11 +93,58 @@ function bp_core_get_table_prefix() {
 }
 
 /**
- * Format numbers the BuddyPress way
+ * Sort an array of objects or arrays by alphabetically sorting by a specific key/property.
+ *
+ * For instance, if you have an array of WordPress post objects, you can sort
+ * them by post_name as follows:
+ *     $sorted_posts = bp_alpha_sort_by_key( $posts, 'post_name' );
+ *
+ * The main purpose for this function is so that you can avoid having to create
+ * your own awkward callback function for usort().
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param array $items The array to be sorted. Its constituent items can be
+ *        either associative arrays or objects.
+ * @param string|int $key The array index or property name to sort by.
+ * @return array $items The sorted array.
+ */
+function bp_alpha_sort_by_key( $items, $key ) {
+	usort( $items, create_function( '$a, $b', '
+		$values = array( 0 => false, 1 => false, );
+		$func_args = func_get_args();
+		foreach ( $func_args as $indexi => $index ) {
+			if ( isset( $index->' . $key . ' ) ) {
+				$values[ $indexi ] = $index->' . $key . ';
+			} else if ( isset( $index["' . $key . '"] ) ) {
+				$values[ $indexi ] = $index["' . $key . '"];
+			}
+		}
+
+		if ( $values[0] && $values[1] ) {
+			$cmp = strcmp( $values[0], $values[1] );
+			if ( 0 > $cmp ) {
+				$retval = -1;
+			} else if ( 0 < $cmp ) {
+				$retval = 1;
+			} else {
+				$retval = 0;
+			}
+			return $retval;
+		} else {
+			return 0;
+		}
+	') );
+
+	return $items;
+}
+
+/**
+ * Format numbers the BuddyPress way.
  *
- * @param int $number
- * @param bool $decimals
- * @return string
+ * @param int $number The number to be formatted.
+ * @param bool $decimals Whether to use decimals. See {@link number_format_i18n()}.
+ * @return string The formatted number.
  */
 function bp_core_number_format( $number, $decimals = false ) {
 
@@ -131,9 +186,9 @@ function bp_core_number_format( $number, $decimals = false ) {
  * For the second argument, $func_args, you should just pass the value of func_get_args().
  *
  * @since BuddyPress (1.6)
- * @param array $old_args_keys
- * @param array $func_args
- * @return array $new_args
+ * @param array $old_args_keys Old argument indexs, keyed to their positions.
+ * @param array $func_args The parameters passed to the originating function.
+ * @return array $new_args The parsed arguments.
  */
 function bp_core_parse_args_array( $old_args_keys, $func_args ) {
 	$new_args = array();
@@ -148,14 +203,61 @@ function bp_core_parse_args_array( $old_args_keys, $func_args ) {
 }
 
 /**
- * Sanitize an 'order' parameter for use in building SQL queries
+ * Merge user defined arguments into defaults array.
+ *
+ * This function is used throughout BuddyPress to allow for either a string or
+ * array to be merged into another array. It is identical to wp_parse_args()
+ * except it allows for arguments to be passively or aggressively filtered using
+ * the optional $filter_key parameter. If no $filter_key is passed, no filters
+ * are applied.
+ *
+ * @since BuddyPress (r7704)
+ *
+ * @param string|array $args Value to merge with $defaults
+ * @param array $defaults Array that serves as the defaults.
+ * @param string $filter_key String to key the filters from
+ * @return array Merged user defined values with defaults.
+ */
+function bp_parse_args( $args, $defaults = array(), $filter_key = '' ) {
+
+	// Setup a temporary array from $args
+	if ( is_object( $args ) ) {
+		$r = get_object_vars( $args );
+	} elseif ( is_array( $args ) ) {
+		$r =& $args;
+	} else {
+		wp_parse_str( $args, $r );
+	}
+
+	// Passively filter the args before the parse
+	if ( !empty( $filter_key ) ) {
+		$r = apply_filters( 'bp_before_' . $filter_key . '_parse_args', $r );
+	}
+
+	// Parse
+	if ( is_array( $defaults ) && !empty( $defaults ) ) {
+		$r = array_merge( $defaults, $r );
+	}
+
+	// Aggressively filter the args after the parse
+	if ( !empty( $filter_key ) ) {
+		$r = apply_filters( 'bp_after_' . $filter_key . '_parse_args', $r );
+	}
+
+	// Return the parsed results
+	return $r;
+}
+
+/**
+ * Sanitize an 'order' parameter for use in building SQL queries.
  *
  * Strings like 'DESC', 'desc', ' desc' will be interpreted into 'DESC'.
  * Everything else becomes 'ASC'.
  *
- * @since BuddyPress (1.8)
- * @param string $order The 'order' string, as passed to the SQL constructor
- * @return string The sanitized value 'DESC' or 'ASC'
+ * @since BuddyPress (1.8.0)
+ *
+ * @param string $order The 'order' string, as passed to the SQL constructor.
+ * @return string The sanitized value 'DESC' or 'ASC'.
  */
 function bp_esc_sql_order( $order = '' ) {
 	$order = strtoupper( trim( $order ) );
@@ -165,12 +267,13 @@ function bp_esc_sql_order( $order = '' ) {
 /**
  * Are we running username compatibility mode?
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @uses apply_filters() Filter 'bp_is_username_compatibility_mode' to alter
- * @return bool False when compatibility mode is disabled (default); true when enabled
+ * @uses apply_filters() Filter 'bp_is_username_compatibility_mode' to alter.
  * @todo Move to members component?
+ *
+ * @return bool False when compatibility mode is disabled, true when enabled.
+ *         Default: false.
  */
 function bp_is_username_compatibility_mode() {
 	return apply_filters( 'bp_is_username_compatibility_mode', defined( 'BP_ENABLE_USERNAME_COMPATIBILITY_MODE' ) && BP_ENABLE_USERNAME_COMPATIBILITY_MODE );
@@ -179,12 +282,15 @@ function bp_is_username_compatibility_mode() {
 /**
  * Should we use the WP Toolbar?
  *
- * The WP Toolbar, introduced in WP 3.1, is fully supported in BuddyPress as of BP 1.5.
- * For BP 1.6, the WP Toolbar is the default.
+ * The WP Toolbar, introduced in WP 3.1, is fully supported in BuddyPress as
+ * of BP 1.5. For BP 1.6, the WP Toolbar is the default.
  *
- * @return bool False when WP Toolbar support is disabled; true when enabled (default)
- * @since BuddyPress (1.5)
- * @uses apply_filters() Filter 'bp_use_wp_admin_bar' to alter
+ * @since BuddyPress (1.5.0)
+ *
+ * @uses apply_filters() Filter 'bp_use_wp_admin_bar' to alter.
+ *
+ * @return bool False when WP Toolbar support is disabled, true when enabled.
+ *        Default: true.
  */
 function bp_use_wp_admin_bar() {
 	$use_admin_bar = true;
@@ -203,10 +309,12 @@ function bp_use_wp_admin_bar() {
 /** Directory *****************************************************************/
 
 /**
- * Fetches BP pages from the meta table, depending on setup
+ * Fetch a list of BP directory pages from the appropriate meta table.
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @return array|string An array of page IDs, keyed by component names, or an
+ *         empty string if the list is not found.
  */
 function bp_core_get_directory_page_ids() {
 	$page_ids = bp_get_option( 'bp-pages' );
@@ -224,85 +332,102 @@ function bp_core_get_directory_page_ids() {
 }
 
 /**
- * Stores BP pages in the meta table, depending on setup
+ * Store the list of BP directory pages in the appropriate meta table.
  *
- * bp-pages data is stored in site_options (falls back to options on non-MS), in an array keyed by
- * blog_id. This allows you to change your bp_get_root_blog_id() and go through the setup process again.
+ * bp-pages data is stored in site_options (falls back to options on non-MS),
+ * in an array keyed by blog_id. This allows you to change your
+ * bp_get_root_blog_id() and go through the setup process again.
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param array $blog_page_ids The IDs of the WP pages corresponding to BP component directories
+ * @param array $blog_page_ids The IDs of the WP pages corresponding to BP
+ *        component directories.
  */
 function bp_core_update_directory_page_ids( $blog_page_ids ) {
 	bp_update_option( 'bp-pages', $blog_page_ids );
 }
 
 /**
- * Get bp-pages names and slugs
+ * Get names and slugs for BuddyPress component directory pages.
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0).
  *
- * @return object Page names, IDs, and slugs
+ * @return object Page names, IDs, and slugs.
  */
 function bp_core_get_directory_pages() {
 	global $wpdb;
 
-	// Set pages as standard class
-	$pages = new stdClass;
+	// Look in cache first
+	$pages = wp_cache_get( 'directory_pages', 'bp' );
 
-	// Get pages and IDs
-	$page_ids = bp_core_get_directory_page_ids();
-	if ( !empty( $page_ids ) ) {
+	if ( false === $pages ) {
 
-		// Always get page data from the root blog, except on multiblog mode, when it comes
-		// from the current blog
-		$posts_table_name = bp_is_multiblog_mode() ? $wpdb->posts : $wpdb->get_blog_prefix( bp_get_root_blog_id() ) . 'posts';
-		$page_ids_sql     = implode( ',', wp_parse_id_list( $page_ids ) );
-		$page_names       = $wpdb->get_results( "SELECT ID, post_name, post_parent, post_title FROM {$posts_table_name} WHERE ID IN ({$page_ids_sql}) AND post_status = 'publish' " );
+		// Set pages as standard class
+		$pages = new stdClass;
 
-		foreach ( (array) $page_ids as $component_id => $page_id ) {
-			foreach ( (array) $page_names as $page_name ) {
-				if ( $page_name->ID == $page_id ) {
-					if ( !isset( $pages->{$component_id} ) || !is_object( $pages->{$component_id} ) ) {
-						$pages->{$component_id} = new stdClass;
-					}
+		// Get pages and IDs
+		$page_ids = bp_core_get_directory_page_ids();
+		if ( !empty( $page_ids ) ) {
 
-					$pages->{$component_id}->name  = $page_name->post_name;
-					$pages->{$component_id}->id    = $page_name->ID;
-					$pages->{$component_id}->title = $page_name->post_title;
-					$slug[]                        = $page_name->post_name;
+			// Always get page data from the root blog, except on multiblog mode, when it comes
+			// from the current blog
+			$posts_table_name = bp_is_multiblog_mode() ? $wpdb->posts : $wpdb->get_blog_prefix( bp_get_root_blog_id() ) . 'posts';
+			$page_ids_sql     = implode( ',', wp_parse_id_list( $page_ids ) );
+			$page_names       = $wpdb->get_results( "SELECT ID, post_name, post_parent, post_title FROM {$posts_table_name} WHERE ID IN ({$page_ids_sql}) AND post_status = 'publish' " );
 
-					// Get the slug
-					while ( $page_name->post_parent != 0 ) {
-						$parent                 = $wpdb->get_results( $wpdb->prepare( "SELECT post_name, post_parent FROM {$posts_table_name} WHERE ID = %d", $page_name->post_parent ) );
-						$slug[]                 = $parent[0]->post_name;
-						$page_name->post_parent = $parent[0]->post_parent;
+			foreach ( (array) $page_ids as $component_id => $page_id ) {
+				foreach ( (array) $page_names as $page_name ) {
+					if ( $page_name->ID == $page_id ) {
+						if ( !isset( $pages->{$component_id} ) || !is_object( $pages->{$component_id} ) ) {
+							$pages->{$component_id} = new stdClass;
+						}
+
+						$pages->{$component_id}->name  = $page_name->post_name;
+						$pages->{$component_id}->id    = $page_name->ID;
+						$pages->{$component_id}->title = $page_name->post_title;
+						$slug[]                        = $page_name->post_name;
+
+						// Get the slug
+						while ( $page_name->post_parent != 0 ) {
+							$parent                 = $wpdb->get_results( $wpdb->prepare( "SELECT post_name, post_parent FROM {$posts_table_name} WHERE ID = %d", $page_name->post_parent ) );
+							$slug[]                 = $parent[0]->post_name;
+							$page_name->post_parent = $parent[0]->post_parent;
+						}
+
+						$pages->{$component_id}->slug = implode( '/', array_reverse( (array) $slug ) );
 					}
 
-					$pages->{$component_id}->slug = implode( '/', array_reverse( (array) $slug ) );
+					unset( $slug );
 				}
-
-				unset( $slug );
 			}
 		}
+
+		wp_cache_set( 'directory_pages', $pages, 'bp' );
 	}
 
 	return apply_filters( 'bp_core_get_directory_pages', $pages );
 }
 
 /**
- * Add the pages for the component mapping. These are most often used by components with directories (e.g. groups, members).
+ * Creates necessary directory pages.
+ *
+ * Directory pages are those WordPress pages used by BP components to display
+ * content (eg, the 'groups' page created by BP).
  *
- * @param array $default_components Optional components to create pages for
+ * @since BuddyPress (1.7.0)
+ *
+ * @param array $components Components to create pages for.
  * @param string $existing 'delete' if you want to delete existing page
- *   mappings and replace with new ones. Otherwise existing page mappings
- *   are kept, and the gaps filled in with new pages
- * @since BuddyPress (1.7)
+ *        mappings and replace with new ones. Otherwise existing page mappings
+ *        are kept, and the gaps filled in with new pages. Default: 'keep'.
  */
 function bp_core_add_page_mappings( $components, $existing = 'keep' ) {
 
+	// If no value is passed, there's nothing to do.
+	if ( empty( $components ) ) {
+		return;
+	}
+
 	// Make sure that the pages are created on the root blog no matter which Dashboard the setup is being run on
 	if ( ! bp_is_root_blog() )
 		switch_to_blog( bp_get_root_blog_id() );
@@ -374,27 +499,27 @@ function bp_core_add_page_mappings( $components, $existing = 'keep' ) {
 }
 
 /**
- * Creates a default component slug from a WP page root_slug
+ * Create a default component slug from a WP page root_slug.
  *
  * Since 1.5, BP components get their root_slug (the slug used immediately
  * following the root domain) from the slug of a corresponding WP page.
  *
  * E.g. if your BP installation at example.com has its members page at
- * example.com/community/people, $bp->members->root_slug will be 'community/people'.
+ * example.com/community/people, $bp->members->root_slug will be
+ * 'community/people'.
  *
  * By default, this function creates a shorter version of the root_slug for
  * use elsewhere in the URL, by returning the content after the final '/'
  * in the root_slug ('people' in the example above).
  *
  * Filter on 'bp_core_component_slug_from_root_slug' to override this method
- * in general, or define a specific component slug constant (e.g. BP_MEMBERS_SLUG)
- * to override specific component slugs.
+ * in general, or define a specific component slug constant (e.g.
+ * BP_MEMBERS_SLUG) to override specific component slugs.
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param string $root_slug The root slug, which comes from $bp->pages->[component]->slug
- * @return string The short slug for use in the middle of URLs
+ * @param string $root_slug The root slug, which comes from $bp->pages->[component]->slug.
+ * @return string The short slug for use in the middle of URLs.
  */
 function bp_core_component_slug_from_root_slug( $root_slug ) {
 	$slug_chunks = explode( '/', $root_slug );
@@ -404,25 +529,34 @@ function bp_core_component_slug_from_root_slug( $root_slug ) {
 }
 
 /**
- * This function originally let plugins add support for pages in the root of the install.
- * These root level pages are now handled by actual WordPress pages and this function is now
- * a convenience for compatibility with the new method.
+ * Add support for a top-level ("root") component.
+ *
+ * This function originally (pre-1.5) let plugins add support for pages in the
+ * root of the install. These root level pages are now handled by actual
+ * WordPress pages and this function is now a convenience for compatibility
+ * with the new method.
  *
- * @global $bp BuddyPress global settings
- * @param string $slug The slug of the component
+ * @param string $slug The slug of the component being added to the root list.
  */
 function bp_core_add_root_component( $slug ) {
-	global $bp;
+	$bp = buddypress();
 
-	if ( empty( $bp->pages ) )
+	if ( empty( $bp->pages ) ) {
 		$bp->pages = bp_core_get_directory_pages();
+	}
 
 	$match = false;
 
 	// Check if the slug is registered in the $bp->pages global
 	foreach ( (array) $bp->pages as $key => $page ) {
-		if ( $key == $slug || $page->slug == $slug )
+		if ( $key == $slug || $page->slug == $slug ) {
 			$match = true;
+		}
+	}
+
+	// Maybe create the add_root array
+	if ( empty( $bp->add_root ) ) {
+		$bp->add_root = array();
 	}
 
 	// If there was no match, add a page for this root component
@@ -437,21 +571,32 @@ function bp_core_add_root_component( $slug ) {
 	}
 }
 
+/**
+ * Create WordPress pages to be used as BP component directories.
+ */
 function bp_core_create_root_component_page() {
-	global $bp;
+
+	// Get BuddyPress
+	$bp = buddypress();
 
 	$new_page_ids = array();
 
-	foreach ( (array) $bp->add_root as $slug )
-		$new_page_ids[$slug] = wp_insert_post( array( 'comment_status' => 'closed', 'ping_status' => 'closed', 'post_title' => ucwords( $slug ), 'post_status' => 'publish', 'post_type' => 'page' ) );
+	foreach ( (array) $bp->add_root as $slug ) {
+		$new_page_ids[ $slug ] = wp_insert_post( array(
+			'comment_status' => 'closed',
+			'ping_status'    => 'closed',
+			'post_title'     => ucwords( $slug ),
+			'post_status'    => 'publish',
+			'post_type'      => 'page'
+		) );
+	}
 
 	$page_ids = array_merge( (array) $new_page_ids, (array) bp_core_get_directory_page_ids() );
 	bp_core_update_directory_page_ids( $page_ids );
 }
 
 /**
- * Adds illegal names to WP so that root components will not conflict with
- * blog names on a subdirectory installation.
+ * Add illegal blog names to WP so that root components will not conflict with blog names on a subdirectory installation.
  *
  * For example, it would stop someone creating a blog with the slug "groups".
  *
@@ -461,14 +606,45 @@ function bp_core_add_illegal_names() {
 	update_site_option( 'illegal_names', get_site_option( 'illegal_names' ), array() );
 }
 
+/**
+ * Determine whether BuddyPress should register the bp-themes directory.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return bool True if bp-themes should be registered, false otherwise.
+ */
+function bp_do_register_theme_directory() {
+	// If bp-default exists in another theme directory, bail.
+	// This ensures that the version of bp-default in the regular themes
+	// directory will always take precedence, as part of a migration away
+	// from the version packaged with BuddyPress
+	foreach ( array_values( (array) $GLOBALS['wp_theme_directories'] ) as $directory ) {
+		if ( is_dir( $directory . '/bp-default' ) ) {
+			return false;
+		}
+	}
+
+	// If the current theme is bp-default (or a bp-default child), BP
+	// should register its directory
+	$register = 'bp-default' === get_stylesheet() || 'bp-default' === get_template();
+
+	// Legacy sites continue to have the theme registered
+	if ( empty( $register ) && ( 1 == get_site_option( '_bp_retain_bp_default' ) ) ) {
+		$register = true;
+	}
+
+	return apply_filters( 'bp_do_register_theme_directory', $register );
+}
+
 /** URI ***********************************************************************/
 
 /**
- * Returns the domain for the root blog.
- * eg: http://domain.com/ OR https://domain.com
+ * Return the domain for the root blog.
+ *
+ * eg: http://domain.com OR https://domain.com
  *
- * @package BuddyPress Core
  * @uses get_blog_option() WordPress function to fetch blog meta.
+ *
  * @return string The domain URL for the blog.
  */
 function bp_core_get_root_domain() {
@@ -479,10 +655,13 @@ function bp_core_get_root_domain() {
 }
 
 /**
- * Performs a status safe wp_redirect() that is compatible with bp_catch_uri()
+ * Perform a status-safe wp_redirect() that is compatible with BP's URI parser.
  *
- * @package BuddyPress Core
  * @uses wp_safe_redirect()
+ *
+ * @param string $location The redirect URL.
+ * @param int $status Optional. The numeric code to give in the redirect
+ *        headers. Default: 302.
  */
 function bp_core_redirect( $location, $status = 302 ) {
 
@@ -501,10 +680,9 @@ function bp_core_redirect( $location, $status = 302 ) {
 }
 
 /**
- * Returns the referrer URL without the http(s)://
+ * Return the referrer URL without the http(s)://
  *
- * @package BuddyPress Core
- * @return string The referrer URL
+ * @return string The referrer URL.
  */
 function bp_core_referrer() {
 	$referer = explode( '/', wp_get_referer() );
@@ -515,10 +693,9 @@ function bp_core_referrer() {
 /**
  * Get the path of of the current site.
  *
- * @package BuddyPress Core
- *
  * @global object $current_site
- * @return string
+ *
+ * @return string URL to the current site.
  */
 function bp_core_get_site_path() {
 	global $current_site;
@@ -549,10 +726,12 @@ function bp_core_get_site_path() {
 /** Time **********************************************************************/
 
 /**
- * Get the current GMT time to save into the DB
+ * Get the current GMT time to save into the DB.
  *
- * @package BuddyPress Core
  * @since BuddyPress (1.2.6)
+ *
+ * @param bool $gmt True to use GMT (rather than local) time. Default: true.
+ * @return string Current time in 'Y-m-d h:i:s' format.
  */
 function bp_core_current_time( $gmt = true ) {
 	// Get current time in MYSQL format
@@ -562,6 +741,8 @@ function bp_core_current_time( $gmt = true ) {
 }
 
 /**
+ * Get an English-language representation of the time elapsed since a given date.
+ *
  * Based on function created by Dunstan Orchard - http://1976design.com
  *
  * This function will return an English representation of the time elapsed
@@ -574,12 +755,16 @@ function bp_core_current_time( $gmt = true ) {
  * an interval of 3 minutes will be represented by "3 minutes ago", as will an
  * interval of 3 minutes 59 seconds.
  *
- * @package BuddyPress Core
- * @uses apply_filters() Filter 'bp_core_time_since_pre' to bypass BP's calculations
- * @uses apply_filters() Filter 'bp_core_time_since' to modify BP's calculations
- * @param int $older_date Unix timestamp of date you want to calculate the time since for
- * @param int $newer_date Unix timestamp of date to compare older date to. Default false (current time).
- * @return string The time since.
+ * @uses apply_filters() Filter 'bp_core_time_since_pre' to bypass BP's calculations.
+ * @uses apply_filters() Filter 'bp_core_time_since' to modify BP's calculations.
+ *
+ * @param int|string $older_date The earlier time from which you're calculating
+ *        the time elapsed. Enter either as an integer Unix timestamp, or as a
+ *        date string of the format 'Y-m-d h:i:s'.
+ * @param int $newer_date Optional. Unix timestamp of date to compare older
+ *        date to. Default: false (current time).
+ * @return string String representing the time since the older date, eg
+ *         "2 hours and 50 minutes".
  */
 function bp_core_time_since( $older_date, $newer_date = false ) {
 
@@ -727,26 +912,26 @@ function bp_core_time_since( $older_date, $newer_date = false ) {
 /** Messages ******************************************************************/
 
 /**
- * Adds a feedback (error/success) message to the WP cookie so it can be
- * displayed after the page reloads.
- *
- * @package BuddyPress Core
+ * Add a feedback (error/success) message to the WP cookie so it can be displayed after the page reloads.
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @param string $message Feedback to give to user
- * @param string $type updated|success|error|warning
+ * @param string $message Feedback message to be displayed.
+ * @param string $type Message type. 'updated', 'success', 'error', 'warning'.
+ *        Default: 'success'.
  */
 function bp_core_add_message( $message, $type = '' ) {
-	global $bp;
 
 	// Success is the default
-	if ( empty( $type ) )
+	if ( empty( $type ) ) {
 		$type = 'success';
+	}
 
 	// Send the values to the cookie for page reload display
 	@setcookie( 'bp-message',      $message, time() + 60 * 60 * 24, COOKIEPATH );
 	@setcookie( 'bp-message-type', $type,    time() + 60 * 60 * 24, COOKIEPATH );
 
+	// Get BuddyPress
+	$bp = buddypress();
+
 	/***
 	 * Send the values to the $bp global so we can still output messages
 	 * without a page reload
@@ -756,51 +941,58 @@ function bp_core_add_message( $message, $type = '' ) {
 }
 
 /**
- * Checks if there is a feedback message in the WP cookie, if so, adds a
- * "template_notices" action so that the message can be parsed into the template
- * and displayed to the user.
+ * Set up the display of the 'template_notices' feedback message.
+ *
+ * Checks whether there is a feedback message in the WP cookie and, if so, adds
+ * a "template_notices" action so that the message can be parsed into the
+ * template and displayed to the user.
  *
  * After the message is displayed, it removes the message vars from the cookie
  * so that the message is not shown to the user multiple times.
  *
- * @package BuddyPress Core
- * @global $bp_message The message text
- * @global $bp_message_type The type of message (error/success)
  * @uses setcookie() Sets a cookie value for the user.
  */
 function bp_core_setup_message() {
-	global $bp;
 
-	if ( empty( $bp->template_message ) && isset( $_COOKIE['bp-message'] ) )
+	// Get BuddyPress
+	$bp = buddypress();
+
+	if ( empty( $bp->template_message ) && isset( $_COOKIE['bp-message'] ) ) {
 		$bp->template_message = stripslashes( $_COOKIE['bp-message'] );
+	}
 
-	if ( empty( $bp->template_message_type ) && isset( $_COOKIE['bp-message-type'] ) )
+	if ( empty( $bp->template_message_type ) && isset( $_COOKIE['bp-message-type'] ) ) {
 		$bp->template_message_type = stripslashes( $_COOKIE['bp-message-type'] );
+	}
 
 	add_action( 'template_notices', 'bp_core_render_message' );
 
-	if ( isset( $_COOKIE['bp-message'] ) )
+	if ( isset( $_COOKIE['bp-message'] ) ) {
 		@setcookie( 'bp-message', false, time() - 1000, COOKIEPATH );
-	if ( isset( $_COOKIE['bp-message-type'] ) )
+	}
+
+	if ( isset( $_COOKIE['bp-message-type'] ) ) {
 		@setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH );
+	}
 }
 add_action( 'bp_actions', 'bp_core_setup_message', 5 );
 
 /**
- * Renders a feedback message (either error or success message) to the theme template.
- * The hook action 'template_notices' is used to call this function, it is not called directly.
+ * Render the 'template_notices' feedback message.
  *
- * @package BuddyPress Core
- * @global BuddyPress $bp The one true BuddyPress instance
+ * The hook action 'template_notices' is used to call this function, it is not
+ * called directly.
  */
 function bp_core_render_message() {
-	global $bp;
+
+	// Get BuddyPress
+	$bp = buddypress();
 
 	if ( !empty( $bp->template_message ) ) :
-		$type    = ( 'success' == $bp->template_message_type ) ? 'updated' : 'error';
+		$type    = ( 'success' === $bp->template_message_type ) ? 'updated' : 'error';
 		$content = apply_filters( 'bp_core_render_message_content', $bp->template_message, $type ); ?>
 
-		<div id="message" class="bp-template-notice <?php echo $type; ?>">
+		<div id="message" class="bp-template-notice <?php echo esc_attr( $type ); ?>">
 
 			<?php echo $content; ?>
 
@@ -816,13 +1008,17 @@ function bp_core_render_message() {
 /** Last active ***************************************************************/
 
 /**
- * Record user activity to the database. Many functions use a "last active" feature to
- * show the length of time since the user was last active.
- * This function will update that time as a usermeta setting for the user every 5 minutes.
+ * Listener function for the logged-in user's 'last_activity' metadata.
  *
- * @package BuddyPress Core
- * @global $userdata WordPress user data for the current logged in user.
- * @uses bp_update_user_meta() BP function to update user metadata in the usermeta table.
+ * Many functions use a "last active" feature to show the length of time since
+ * the user was last active. This function will update that time as a usermeta
+ * setting for the user every 5 minutes while the user is actively browsing the
+ * site.
+ *
+ * @uses bp_update_user_meta() BP function to update user metadata in the
+ *       usermeta table.
+ *
+ * @return bool|null Returns false if there is nothing to do.
  */
 function bp_core_record_activity() {
 
@@ -834,7 +1030,7 @@ function bp_core_record_activity() {
 	if ( bp_is_user_inactive( $user_id ) )
 		return false;
 
-	$activity = bp_get_user_meta( $user_id, 'last_activity', true );
+	$activity = bp_get_user_last_activity( $user_id );
 
 	if ( !is_numeric( $activity ) )
 		$activity = strtotime( $activity );
@@ -847,18 +1043,21 @@ function bp_core_record_activity() {
 		do_action( 'bp_first_activity_for_member', $user_id );
 	}
 
-	if ( empty( $activity ) || strtotime( $current_time ) >= strtotime( '+5 minutes', $activity ) )
-		bp_update_user_meta( $user_id, 'last_activity', $current_time );
+	if ( empty( $activity ) || strtotime( $current_time ) >= strtotime( '+5 minutes', $activity ) ) {
+		bp_update_user_last_activity( $user_id, $current_time );
+	}
 }
 add_action( 'wp_head', 'bp_core_record_activity' );
 
 /**
- * Formats last activity based on time since date given.
+ * Format last activity string based on time since date given.
+ *
+ * @uses bp_core_time_since() This function will return an English
+ *       representation of the time elapsed.
  *
- * @package BuddyPress Core
- * @param string $last_activity_date The date of last activity.
- * @param string $string
- * @uses bp_core_time_since() This function will return an English representation of the time elapsed.
+ * @param int|string $last_activity_date The date of last activity.
+ * @param string $string A sprintf()-able statement of the form '% ago'.
+ * @return string $last_active A string of the form '3 years ago'.
  */
 function bp_core_get_last_activity( $last_activity_date, $string ) {
 
@@ -875,81 +1074,87 @@ function bp_core_get_last_activity( $last_activity_date, $string ) {
 /**
  * Get the meta_key for a given piece of user metadata
  *
- * BuddyPress stores a number of pieces of userdata in the WordPress central usermeta table. In
- * order to allow plugins to enable multiple instances of BuddyPress on a single WP installation,
- * BP's usermeta keys are filtered with this function, so that they can be altered on the fly.
- *
- * 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 );
- * If you have to use WP's _user_meta() functions for some reason, you should use this function, eg
- *    $last_active = get_user_meta( $user_id, bp_get_user_meta_key( 'last_activity' ), true );
+ * BuddyPress stores a number of pieces of userdata in the WordPress central
+ * usermeta table. In order to allow plugins to enable multiple instances of
+ * BuddyPress on a single WP installation, BP's usermeta keys are filtered
+ * through this function, so that they can be altered on the fly.
+ *
+ * Plugin authors should use BP's _user_meta() functions, which bakes in
+ * bp_get_user_meta_key():
+ *    $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
+ *    $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.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @uses apply_filters() Filter bp_get_user_meta_key to modify keys individually
- * @param string $key
- * @return string $key
+ * @uses apply_filters() Filter 'bp_get_user_meta_key' to modify keys individually.
+ *
+ * @param string $key The usermeta meta_key.
+ * @return string $key The usermeta meta_key.
  */
 function bp_get_user_meta_key( $key = false ) {
 	return apply_filters( 'bp_get_user_meta_key', $key );
 }
 
 /**
- * Get a piece of usermeta
+ * Get a piece of usermeta.
  *
- * This is a wrapper for get_user_meta() that allows for easy use of bp_get_user_meta_key(), thereby
- * increasing compatibility with non-standard BP setups.
+ * This is a wrapper for get_user_meta() that allows for easy use of
+ * bp_get_user_meta_key(), thereby increasing compatibility with non-standard
+ * BP setups.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @uses bp_get_user_meta_key() For a filterable version of the meta key
- * @uses get_user_meta() See get_user_meta() docs for more details on parameters
- * @param int $user_id The id of the user whose meta you're fetching
+ * @see get_user_meta() For complete details about parameters and return values.
+ * @uses bp_get_user_meta_key() For a filterable version of the meta key.
+ *
+ * @param int $user_id The ID of the user whose meta you're fetching.
  * @param string $key The meta key to retrieve.
  * @param bool $single Whether to return a single value.
  * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
- *  is true.
+ *         is true.
  */
 function bp_get_user_meta( $user_id, $key, $single = false ) {
 	return get_user_meta( $user_id, bp_get_user_meta_key( $key ), $single );
 }
 
 /**
- * Update a piece of usermeta
+ * Update a piece of usermeta.
  *
- * This is a wrapper for update_user_meta() that allows for easy use of bp_get_user_meta_key(),
- * thereby increasing compatibility with non-standard BP setups.
+ * This is a wrapper for update_user_meta() that allows for easy use of
+ * bp_get_user_meta_key(), thereby increasing compatibility with non-standard
+ * BP setups.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @uses bp_get_user_meta_key() For a filterable version of the meta key
- * @uses update_user_meta() See update_user_meta() docs for more details on parameters
- * @param int $user_id The id of the user whose meta you're setting
+ * @see update_user_meta() For complete details about parameters and return values.
+ * @uses bp_get_user_meta_key() For a filterable version of the meta key.
+ *
+ * @param int $user_id The ID of the user whose meta you're setting.
  * @param string $key The meta key to set.
  * @param mixed $value Metadata value.
  * @param mixed $prev_value Optional. Previous value to check before removing.
- * @return bool False on failure, true if success.
+ * @return bool False on failure, true on success.
  */
 function bp_update_user_meta( $user_id, $key, $value, $prev_value = '' ) {
 	return update_user_meta( $user_id, bp_get_user_meta_key( $key ), $value, $prev_value );
 }
 
 /**
- * Delete a piece of usermeta
+ * Delete a piece of usermeta.
  *
- * This is a wrapper for delete_user_meta() that allows for easy use of bp_get_user_meta_key(),
- * thereby increasing compatibility with non-standard BP setups.
+ * This is a wrapper for delete_user_meta() that allows for easy use of
+ * bp_get_user_meta_key(), thereby increasing compatibility with non-standard
+ * BP setups.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @uses bp_get_user_meta_key() For a filterable version of the meta key
- * @uses delete_user_meta() See delete_user_meta() docs for more details on parameters
- * @param int $user_id The id of the user whose meta you're deleting
+ * @see delete_user_meta() For complete details about parameters and return values.
+ * @uses bp_get_user_meta_key() For a filterable version of the meta key.
+ *
+ * @param int $user_id The ID of the user whose meta you're deleting.
  * @param string $key The meta key to delete.
  * @param mixed $value Optional. Metadata value.
  * @return bool False for failure. True for success.
@@ -963,23 +1168,26 @@ function bp_delete_user_meta( $user_id, $key, $value = '' ) {
 /**
  * Initializes {@link BP_Embed} after everything is loaded.
  *
- * @global object $bp BuddyPress global settings
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  */
 function bp_embed_init() {
-	global $bp;
 
-	if ( empty( $bp->embed ) )
+	// Get BuddyPress
+	$bp = buddypress();
+
+	if ( empty( $bp->embed ) ) {
 		$bp->embed = new BP_Embed();
+	}
 }
 add_action( 'bp_init', 'bp_embed_init', 9 );
 
 /**
  * Are oembeds allowed in activity items?
  *
- * @return bool False when activity embed support is disabled; true when enabled (default)
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool False when activity embed support is disabled; true when
+ *         enabled. Default: true.
  */
 function bp_use_embed_in_activity() {
 	return apply_filters( 'bp_use_oembed_in_activity', !defined( 'BP_EMBED_DISABLE_ACTIVITY' ) || !BP_EMBED_DISABLE_ACTIVITY );
@@ -988,8 +1196,10 @@ function bp_use_embed_in_activity() {
 /**
  * Are oembeds allwoed in activity replies?
  *
- * @return bool False when activity replies embed support is disabled; true when enabled (default)
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool False when activity replies embed support is disabled; true
+ *         when enabled. Default: true.
  */
 function bp_use_embed_in_activity_replies() {
 	return apply_filters( 'bp_use_embed_in_activity_replies', !defined( 'BP_EMBED_DISABLE_ACTIVITY_REPLIES' ) || !BP_EMBED_DISABLE_ACTIVITY_REPLIES );
@@ -998,8 +1208,10 @@ function bp_use_embed_in_activity_replies() {
 /**
  * Are oembeds allowed in forum posts?
  *
- * @return bool False when form post embed support is disabled; true when enabled (default)
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool False when forum post embed support is disabled; true when
+ *         enabled. Default: true.
  */
 function bp_use_embed_in_forum_posts() {
 	return apply_filters( 'bp_use_embed_in_forum_posts', !defined( 'BP_EMBED_DISABLE_FORUM_POSTS' ) || !BP_EMBED_DISABLE_FORUM_POSTS );
@@ -1008,8 +1220,10 @@ function bp_use_embed_in_forum_posts() {
 /**
  * Are oembeds allowed in private messages?
  *
- * @return bool False when form post embed support is disabled; true when enabled (default)
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool False when private message embed support is disabled; true when
+ *         enabled. Default: true.
  */
 function bp_use_embed_in_private_messages() {
 	return apply_filters( 'bp_use_embed_in_private_messages', !defined( 'BP_EMBED_DISABLE_PRIVATE_MESSAGES' ) || !BP_EMBED_DISABLE_PRIVATE_MESSAGES );
@@ -1018,31 +1232,33 @@ function bp_use_embed_in_private_messages() {
 /** Admin *********************************************************************/
 
 /**
- * Output the correct URL based on BuddyPress and WordPress configuration
+ * Output the correct admin URL based on BuddyPress and WordPress configuration.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param string $path
- * @param string $scheme
+ * @see bp_get_admin_url() For description of parameters.
  *
- * @uses bp_get_admin_url()
+ * @param string $path See {@link bp_get_admin_url()}.
+ * @param string $scheme See {@link bp_get_admin_url()}.
  */
 function bp_admin_url( $path = '', $scheme = 'admin' ) {
 	echo bp_get_admin_url( $path, $scheme );
 }
 	/**
-	 * Return the correct URL based on BuddyPress and WordPress configuration
-	 *
-	 * @package BuddyPress
-	 * @since BuddyPress (1.5)
+	 * Return the correct admin URL based on BuddyPress and WordPress configuration.
 	 *
-	 * @param string $path
-	 * @param string $scheme
+	 * @since BuddyPress (1.5.0)
 	 *
 	 * @uses bp_core_do_network_admin()
 	 * @uses network_admin_url()
 	 * @uses admin_url()
+	 *
+	 * @param string $path Optional. The sub-path under /wp-admin to be
+	 *        appended to the admin URL.
+	 * @param string $scheme The scheme to use. Default is 'admin', which
+	 *        obeys {@link force_ssl_admin()} and {@link is_ssl()}. 'http'
+	 *        or 'https' can be passed to force those schemes.
+	 * @return string Admin url link with optional path appended.
 	 */
 	function bp_get_admin_url( $path = '', $scheme = 'admin' ) {
 
@@ -1059,18 +1275,19 @@ function bp_admin_url( $path = '', $scheme = 'admin' ) {
 	}
 
 /**
- * Should BuddyPress appear in network admin, or site admin?
+ * Should BuddyPress appear in network admin (vs a single site Dashboard)?
  *
  * Because BuddyPress can be installed in multiple ways and with multiple
  * configurations, we need to check a few things to be confident about where
  * to hook into certain areas of WordPress's admin.
  *
- * This function defaults to BuddyPress being network activated.
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_is_network_activated()
  * @uses bp_is_multiblog_mode()
- * @return boolean
+ *
+ * @return bool True if the BP admin screen should appear in the Network Admin,
+ *         otherwise false.
  */
 function bp_core_do_network_admin() {
 
@@ -1083,6 +1300,18 @@ function bp_core_do_network_admin() {
 	return (bool) apply_filters( 'bp_core_do_network_admin', $retval );
 }
 
+/**
+ * Return the action name that BuddyPress nav setup callbacks should be hooked to.
+ *
+ * Functions used to set up BP Dashboard pages (wrapping such admin-panel
+ * functions as add_submenu_page()) should use bp_core_admin_hook() for the
+ * first parameter in add_action(). BuddyPress will then determine
+ * automatically whether to load the panels in the Network Admin. Ie:
+ *
+ *     add_action( bp_core_admin_hook(), 'myplugin_dashboard_panel_setup' );
+ *
+ * @return string $hook The proper hook ('network_admin_menu' or 'admin_menu').
+ */
 function bp_core_admin_hook() {
 	$hook = bp_core_do_network_admin() ? 'network_admin_menu' : 'admin_menu';
 
@@ -1092,12 +1321,11 @@ function bp_core_admin_hook() {
 /** Multisite *****************************************************************/
 
 /**
- * Is this the root blog ID?
+ * Is this the root blog?
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param int $blog_id Optional. Defaults to the current blog id.
+ * @param int $blog_id Optional. Default: the ID of the current blog.
  * @return bool $is_root_blog Returns true if this is bp_get_root_blog_id().
  */
 function bp_is_root_blog( $blog_id = 0 ) {
@@ -1117,17 +1345,18 @@ function bp_is_root_blog( $blog_id = 0 ) {
 }
 
 /**
- * Is this bp_get_root_blog_id()?
+ * Get the ID of the root blog.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * The "root blog" is the blog on a WordPress network where BuddyPress content
+ * appears (where member profile URLs resolve, where a given theme is loaded,
+ * etc.).
+ *
+ * @since BuddyPress (1.5.0)
  *
- * @return int Return the root site ID
+ * @return int The root site ID.
  */
 function bp_get_root_blog_id() {
-	global $bp;
-
-	return (int) apply_filters( 'bp_get_root_blog_id', (int) $bp->root_blog_id );
+	return (int) apply_filters( 'bp_get_root_blog_id', (int) buddypress()->root_blog_id );
 }
 
 /**
@@ -1153,11 +1382,12 @@ function bp_get_root_blog_id() {
  * a very small use-case with large architectural shortcomings, so do not go
  * down this road unless you specifically need to.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @uses apply_filters() Filter 'bp_is_multiblog_mode' to alter
- * @return bool False when multiblog mode is disabled (default); true when enabled
+ * @uses apply_filters() Filter 'bp_is_multiblog_mode' to alter.
+ *
+ * @return bool False when multiblog mode is disabled; true when enabled.
+ *         Default: false.
  */
 function bp_is_multiblog_mode() {
 
@@ -1184,10 +1414,12 @@ function bp_is_multiblog_mode() {
  *
  * Used to determine admin menu placement, and where settings and options are
  * stored. If you're being *really* clever and manually pulling BuddyPress in
- * with an mu-plugin or some other method, you'll want to
+ * with an mu-plugin or some other method, you'll want to filter
+ * 'bp_is_network_activated' and override the auto-determined value.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
- * @return boolean
+ * @return bool True if BuddyPress is network activated.
  */
 function bp_is_network_activated() {
 
@@ -1208,60 +1440,62 @@ function bp_is_network_activated() {
 /** Global Manipulators *******************************************************/
 
 /**
- * Set the $bp->is_directory global
+ * Set the "is_directory" global.
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @param bool $is_directory
- * @param string $component
+ * @param bool $is_directory Optional. Default: false.
+ * @param string $component Optional. Component name. Default: the current
+ *        component.
  */
 function bp_update_is_directory( $is_directory = false, $component = '' ) {
-	global $bp;
 
-	if ( empty( $component ) )
+	if ( empty( $component ) ) {
 		$component = bp_current_component();
+	}
 
-	$bp->is_directory = apply_filters( 'bp_update_is_directory', $is_directory, $component );
+	buddypress()->is_directory = apply_filters( 'bp_update_is_directory', $is_directory, $component );
 }
 
 /**
- * Set the $bp->is_item_admin global
+ * Set the "is_item_admin" global.
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @param bool $is_item_admin
- * @param string $component
+ * @param bool $is_item_admin Optional. Default: false.
+ * @param string $component Optional. Component name. Default: the current
+ *        component.
  */
 function bp_update_is_item_admin( $is_item_admin = false, $component = '' ) {
-	global $bp;
 
-	if ( empty( $component ) )
+	if ( empty( $component ) ) {
 		$component = bp_current_component();
+	}
 
-	$bp->is_item_admin = apply_filters( 'bp_update_is_item_admin', $is_item_admin, $component );
+	buddypress()->is_item_admin = apply_filters( 'bp_update_is_item_admin', $is_item_admin, $component );
 }
 
 /**
- * Set the $bp->is_item_mod global
+ * Set the "is_item_mod" global.
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @param bool $is_item_mod
- * @param string $component
+ * @param bool $is_item_mod Optional. Default: false.
+ * @param string $component Optional. Component name. Default: the current
+ *        component.
  */
 function bp_update_is_item_mod( $is_item_mod = false, $component = '' ) {
-	global $bp;
 
-	if ( empty( $component ) )
+	if ( empty( $component ) ) {
 		$component = bp_current_component();
+	}
 
-	$bp->is_item_mod = apply_filters( 'bp_update_is_item_mod', $is_item_mod, $component );
+	buddypress()->is_item_mod = apply_filters( 'bp_update_is_item_mod', $is_item_mod, $component );
 }
 
 /**
- * Trigger a 404
+ * Trigger a 404.
+ *
+ * @since BuddyPress (1.5.0)
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @global WP_Query $wp_query WordPress query object
- * @param string $redirect If 'remove_canonical_direct', remove WordPress' "helpful" redirect_canonical action.
- * @since BuddyPress (1.5)
+ * @global WP_Query $wp_query WordPress query object.
+ *
+ * @param string $redirect If 'remove_canonical_direct', remove WordPress'
+ *        "helpful" redirect_canonical action. Default: 'remove_canonical_redirect'.
  */
 function bp_do_404( $redirect = 'remove_canonical_direct' ) {
 	global $wp_query;
@@ -1272,8 +1506,9 @@ function bp_do_404( $redirect = 'remove_canonical_direct' ) {
 	status_header( 404 );
 	nocache_headers();
 
-	if ( 'remove_canonical_direct' == $redirect )
+	if ( 'remove_canonical_direct' === $redirect ) {
 		remove_action( 'template_redirect', 'redirect_canonical' );
+	}
 }
 
 /** Nonces ********************************************************************/
@@ -1283,25 +1518,57 @@ function bp_do_404( $redirect = 'remove_canonical_direct' ) {
  *
  * To avoid security exploits within the theme.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
  * @uses do_action() Calls 'bp_verify_nonce_request' on $action.
- * @param string $action Action nonce
- * @param string $query_arg where to look for nonce in $_REQUEST
+ *
+ * @param string $action Action nonce.
+ * @param string $query_arg where to look for nonce in $_REQUEST.
+ * @return bool True if the nonce is verified, otherwise false.
  */
 function bp_verify_nonce_request( $action = '', $query_arg = '_wpnonce' ) {
 
-	// Get the home URL
-	$home_url = strtolower( home_url() );
+	/** Home URL **************************************************************/
+
+	// Parse home_url() into pieces to remove query-strings, strange characters,
+	// and other funny things that plugins might to do to it.
+	$parsed_home = parse_url( home_url( '/', ( is_ssl() ? 'https://' : 'http://' ) ) );
+
+	// Maybe include the port, if it's included
+	if ( isset( $parsed_home['port'] ) ) {
+		$parsed_host = $parsed_home['host'] . ':' . $parsed_home['port'];
+	} else {
+		$parsed_host = $parsed_home['host'];
+	}
+
+	// Set the home URL for use in comparisons
+	$home_url = trim( strtolower( $parsed_home['scheme'] . '://' . $parsed_host . $parsed_home['path'] ), '/' );
+
+	/** Requested URL *********************************************************/
+
+	// Maybe include the port, if it's included in home_url()
+	if ( isset( $parsed_home['port'] ) ) {
+		$request_host = $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'];
+	} else {
+		$request_host = $_SERVER['HTTP_HOST'];
+	}
+
+	// Build the currently requested URL
+	$scheme        = is_ssl() ? 'https://' : 'http://';
+	$requested_url = strtolower( $scheme . $request_host . $_SERVER['REQUEST_URI'] );
+
+	/** Look for match ********************************************************/
 
-	$requested_url = bp_get_requested_url();
+	// Filter the requested URL, for configurations like reverse proxying
+	$matched_url = apply_filters( 'bp_verify_nonce_request_url', $requested_url );
 
 	// Check the nonce
 	$result = isset( $_REQUEST[$query_arg] ) ? wp_verify_nonce( $_REQUEST[$query_arg], $action ) : false;
 
 	// Nonce check failed
-	if ( empty( $result ) || empty( $action ) || ( strpos( $requested_url, $home_url ) !== 0 ) )
+	if ( empty( $result ) || empty( $action ) || ( strpos( $matched_url, $home_url ) !== 0 ) ) {
 		$result = false;
+	}
 
 	// Do extra things
 	do_action( 'bp_verify_nonce_request', $action, $result );
@@ -1309,12 +1576,37 @@ function bp_verify_nonce_request( $action = '', $query_arg = '_wpnonce' ) {
 	return $result;
 }
 
+/** Requests ******************************************************************/
+
+/**
+ * Return true|false if this is a POST request
+ *
+ * @since BuddyPress (1.9.0)
+ * @return bool
+ */
+function bp_is_post_request() {
+	return (bool) ( 'POST' === strtoupper( $_SERVER['REQUEST_METHOD'] ) );
+}
+
+/**
+ * Return true|false if this is a GET request
+ *
+ * @since BuddyPress (1.9.0)
+ * @return bool
+ */
+function bp_is_get_request() {
+	return (bool) ( 'GET' === strtoupper( $_SERVER['REQUEST_METHOD'] ) );
+}
+
+
 /** Miscellaneous hooks *******************************************************/
 
 /**
- * Load the buddypress translation file for current language
+ * Load the buddypress translation file for current language.
+ *
+ * @see load_textdomain() for a description of return values.
  *
- * @package BuddyPress Core
+ * @return bool True on success, false on failure.
  */
 function bp_core_load_buddypress_textdomain() {
 	// Try to load via load_plugin_textdomain() first, for future
@@ -1332,9 +1624,8 @@ function bp_core_load_buddypress_textdomain() {
 add_action ( 'bp_core_loaded', 'bp_core_load_buddypress_textdomain' );
 
 /**
- * A javascript free implementation of the search functions in BuddyPress
+ * A javascript-free implementation of the search functions in BuddyPress.
  *
- * @package BuddyPress Core
  * @param string $slug The slug to redirect to for searching.
  */
 function bp_core_action_search_site( $slug = '' ) {
@@ -1398,9 +1689,7 @@ function bp_core_action_search_site( $slug = '' ) {
 add_action( 'bp_init', 'bp_core_action_search_site', 7 );
 
 /**
- * Prints the generation time in the footer of the site.
- *
- * @package BuddyPress Core
+ * Print the generation time in the footer of the site.
  */
 function bp_core_print_generation_time() {
 ?>
@@ -1410,3 +1699,191 @@ function bp_core_print_generation_time() {
 	<?php
 }
 add_action( 'wp_footer', 'bp_core_print_generation_time' );
+
+/** Nav Menu ******************************************************************/
+
+/**
+ * Create fake "post" objects for BP's logged-in nav menu for use in the WordPress "Menus" settings page.
+ *
+ * WordPress nav menus work by representing post or tax term data as a custom
+ * post type, which is then used to populate the checkboxes that appear on
+ * Dashboard > Appearance > Menu as well as the menu as rendered on the front
+ * end. Most of the items in the BuddyPress set of nav items are neither posts
+ * nor tax terms, so we fake a post-like object so as to be compatible with the
+ * menu.
+ *
+ * This technique also allows us to generate links dynamically, so that, for
+ * example, "My Profile" will always point to the URL of the profile of the
+ * logged-in user.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return mixed A URL or an array of dummy pages.
+ */
+function bp_nav_menu_get_loggedin_pages() {
+
+	// Try to catch the cached version first
+	if ( ! empty( buddypress()->wp_nav_menu_items->loggedin ) ) {
+		return buddypress()->wp_nav_menu_items->loggedin;
+	}
+
+	// Pull up a list of items registered in BP's top-level nav array
+	$bp_menu_items = buddypress()->bp_nav;
+
+	// Alphabetize
+	$bp_menu_items = bp_alpha_sort_by_key( $bp_menu_items, 'name' );
+
+	// Some BP nav menu items will not be represented in bp_nav, because
+	// they are not real BP components. We add them manually here.
+	$bp_menu_items[] = array(
+		'name' => __( 'Log Out', 'buddypress' ),
+		'slug' => 'logout',
+		'link' => wp_logout_url(),
+	);
+
+	// If there's nothing to show, we're done
+	if ( count( $bp_menu_items ) < 1 ) {
+		return false;
+	}
+
+	$page_args = array();
+
+	foreach ( $bp_menu_items as $bp_item ) {
+		$item_name = '';
+
+		// Remove <span>number</span>
+		$item_name = preg_replace( '/([.0-9]+)/', '', $bp_item['name'] );
+		$item_name = trim( strip_tags( $item_name ) );
+
+		$page_args[ $bp_item['slug'] ] = (object) array(
+			'ID'             => -1,
+			'post_title'     => $item_name,
+			'post_author'    => 0,
+			'post_date'      => 0,
+			'post_excerpt'   => $bp_item['slug'],
+			'post_type'      => 'page',
+			'post_status'    => 'publish',
+			'comment_status' => 'closed',
+			'guid'           => $bp_item['link']
+		);
+	}
+
+	if ( empty( buddypress()->wp_nav_menu_items ) ) {
+		buddypress()->wp_nav_menu_items = new stdClass;
+	}
+
+	buddypress()->wp_nav_menu_items->loggedin = $page_args;
+
+	return $page_args;
+}
+
+/**
+ * Create fake "post" objects for BP's logged-out nav menu for use in the WordPress "Menus" settings page.
+ *
+ * WordPress nav menus work by representing post or tax term data as a custom
+ * post type, which is then used to populate the checkboxes that appear on
+ * Dashboard > Appearance > Menu as well as the menu as rendered on the front
+ * end. Most of the items in the BuddyPress set of nav items are neither posts
+ * nor tax terms, so we fake a post-like object so as to be compatible with the
+ * menu.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return mixed A URL or an array of dummy pages.
+ */
+function bp_nav_menu_get_loggedout_pages() {
+
+	// Try to catch the cached version first
+	if ( ! empty( buddypress()->wp_nav_menu_items->loggedout ) ) {
+		return buddypress()->wp_nav_menu_items->loggedout;
+	}
+
+	$bp_menu_items = array();
+
+	// Some BP nav menu items will not be represented in bp_nav, because
+	// they are not real BP components. We add them manually here.
+	$bp_menu_items[] = array(
+		'name' => __( 'Log In', 'buddypress' ),
+		'slug' => 'login',
+		'link' => wp_login_url(),
+	);
+
+	// The Register page will not always be available (ie, when
+	// registration is disabled)
+	$bp_directory_page_ids = bp_core_get_directory_page_ids();
+
+	if( ! empty( $bp_directory_page_ids['register'] ) ) {
+		$register_page = get_post( $bp_directory_page_ids['register'] );
+		$bp_menu_items[] = array(
+			'name' => $register_page->post_title,
+			'slug' => 'register',
+			'link' => get_permalink( $register_page->ID ),
+		);
+	}
+
+	// If there's nothing to show, we're done
+	if ( count( $bp_menu_items ) < 1 ) {
+		return false;
+	}
+
+	$page_args = array();
+
+	foreach ( $bp_menu_items as $bp_item ) {
+		$page_args[ $bp_item['slug'] ] = (object) array(
+			'ID'             => -1,
+			'post_title'     => $bp_item['name'],
+			'post_author'    => 0,
+			'post_date'      => 0,
+			'post_excerpt'   => $bp_item['slug'],
+			'post_type'      => 'page',
+			'post_status'    => 'publish',
+			'comment_status' => 'closed',
+			'guid'           => $bp_item['link']
+		);
+	}
+
+	if ( empty( buddypress()->wp_nav_menu_items ) ) {
+		buddypress()->wp_nav_menu_items = new stdClass;
+	}
+
+	buddypress()->wp_nav_menu_items->loggedout = $page_args;
+
+	return $page_args;
+}
+
+/**
+ * Get the URL for a BuddyPress WP nav menu item, based on slug.
+ *
+ * BuddyPress-specific WP nav menu items have dynamically generated URLs,
+ * based on the identity of the current user. This function lets you fetch the
+ * proper URL for a given nav item slug (such as 'login' or 'messages').
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param string $slug The slug of the nav item: login, register, or one of the
+ *        slugs from buddypress()->bp_nav.
+ * @return string $nav_item_url The URL generated for the current user.
+ */
+function bp_nav_menu_get_item_url( $slug ) {
+	$nav_item_url   = '';
+	$nav_menu_items = bp_nav_menu_get_loggedin_pages();
+
+	if ( isset( $nav_menu_items[ $slug ] ) ) {
+		$nav_item_url = $nav_menu_items[ $slug ]->guid;
+	}
+
+	return $nav_item_url;
+}
+
+/**
+ * Get the javascript dependencies for buddypress.js.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @uses apply_filters() to allow other component to load extra dependencies
+ *
+ * @return array The javascript dependencies.
+ */
+function bp_core_get_js_dependencies() {
+	return apply_filters( 'bp_core_get_js_dependencies', array( 'jquery' ) );
+}
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-loader.php b/wp-content/plugins/buddypress/bp-core/bp-core-loader.php
index d12d286fa5d45a7e727e212b39612068733a5941..b5ce7fecb14401951cf7db0c63f46d0e4d22917a 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-loader.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-loader.php
@@ -1,9 +1,9 @@
 <?php
 
 /**
- * BuddyPress Core Loader
+ * BuddyPress Core Loader.
  *
- * Core contains the commonly used functions, classes, and API's
+ * Core contains the commonly used functions, classes, and APIs.
  *
  * @package BuddyPress
  * @subpackage Core
@@ -15,34 +15,32 @@ if ( !defined( 'ABSPATH' ) ) exit;
 class BP_Core extends BP_Component {
 
 	/**
-	 * Start the members component creation process
+	 * Start the members component creation process.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
 	 * @uses BP_Core::bootstrap()
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'core',
-			__( 'BuddyPress Core', 'buddypress' )
-			, BP_PLUGIN_DIR
+			__( 'BuddyPress Core', 'buddypress' ),
+			buddypress()->plugin_dir
 		);
 
 		$this->bootstrap();
 	}
 
 	/**
-	 * Populate the global data needed before BuddyPress can continue
+	 * Populate the global data needed before BuddyPress can continue.
 	 *
 	 * This involves figuring out the currently required, active, deactive,
 	 * and optional components.
 	 *
-	 * @since BuddyPress (1.5)
-	 *
-	 * @global BuddyPress $bp
+	 * @since BuddyPress (1.5.0)
 	 */
 	private function bootstrap() {
-		global $bp;
+		$bp = buddypress();
 
 		/**
 		 * At this point in the stack, BuddyPress core has been loaded but
@@ -56,7 +54,7 @@ class BP_Core extends BP_Component {
 		/** Components ********************************************************/
 
 		// Set the included and optional components.
-		$bp->optional_components = apply_filters( 'bp_optional_components', array( 'activity', 'blogs', 'forums', 'friends', 'groups', 'messages', 'settings', 'xprofile' ) );
+		$bp->optional_components = apply_filters( 'bp_optional_components', array( 'activity', 'blogs', 'forums', 'friends', 'groups', 'messages', 'notifications', 'settings', 'xprofile' ) );
 
 		// Set the required components
 		$bp->required_components = apply_filters( 'bp_required_components', array( 'members' ) );
@@ -97,19 +95,32 @@ class BP_Core extends BP_Component {
 		}
 
 		// Loop through optional components
-		foreach( $bp->optional_components as $component )
-			if ( bp_is_active( $component ) && file_exists( BP_PLUGIN_DIR . '/bp-' . $component . '/bp-' . $component . '-loader.php' ) )
-				include( BP_PLUGIN_DIR . '/bp-' . $component . '/bp-' . $component . '-loader.php' );
+		foreach( $bp->optional_components as $component ) {
+			if ( bp_is_active( $component ) && file_exists( $bp->plugin_dir . '/bp-' . $component . '/bp-' . $component . '-loader.php' ) ) {
+				include( $bp->plugin_dir . '/bp-' . $component . '/bp-' . $component . '-loader.php' );
+			}
+		}
 
 		// Loop through required components
-		foreach( $bp->required_components as $component )
-			if ( file_exists( BP_PLUGIN_DIR . '/bp-' . $component . '/bp-' . $component . '-loader.php' ) )
-				include( BP_PLUGIN_DIR . '/bp-' . $component . '/bp-' . $component . '-loader.php' );
+		foreach( $bp->required_components as $component ) {
+			if ( file_exists( $bp->plugin_dir . '/bp-' . $component . '/bp-' . $component . '-loader.php' ) ) {
+				include( $bp->plugin_dir . '/bp-' . $component . '/bp-' . $component . '-loader.php' );
+			}
+		}
 
 		// Add Core to required components
 		$bp->required_components[] = 'core';
+
+		do_action( 'bp_core_components_included' );
 	}
 
+	/**
+	 * Include bp-core files.
+	 *
+	 * @see BP_Component::includes() for description of parameters.
+	 *
+	 * @param array $includes See {@link BP_Component::includes()}.
+	 */
 	public function includes( $includes = array() ) {
 
 		if ( !is_admin() )
@@ -123,15 +134,19 @@ class BP_Core extends BP_Component {
 	}
 
 	/**
+	 * Set up bp-core global settings.
+	 *
 	 * Sets up a majority of the BuddyPress globals that require a minimal
 	 * amount of processing, meaning they cannot be set in the BuddyPress class.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @global BuddyPress $bp
+	 * @see BP_Component::setup_globals() for description of parameters.
+	 *
+	 * @param array $args See {@link BP_Component::setup_globals()}.
 	 */
 	public function setup_globals( $args = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		/** Database **********************************************************/
 
@@ -168,7 +183,8 @@ class BP_Core extends BP_Component {
 		$bp->grav_default->group = apply_filters( 'bp_group_gravatar_default', $bp->grav_default->user );
 		$bp->grav_default->blog  = apply_filters( 'bp_blog_gravatar_default',  $bp->grav_default->user );
 
-		// Notifications Table
+		// Notifications table. Included here for legacy purposes. Use
+		// bp-notifications instead.
 		$bp->core->table_name_notifications = $bp->table_prefix . 'bp_notifications';
 
 		/**
@@ -188,21 +204,23 @@ class BP_Core extends BP_Component {
 	}
 
 	/**
-	 * Setup BuddyBar navigation
+	 * Set up component navigation.
+	 *
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @since BuddyPress (1.5)
+	 * @see BP_Component::setup_nav() for a description of arguments.
 	 *
-	 * @global BuddyPress $bp
+	 * @param array $main_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
+	 * @param array $sub_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		 // If xprofile component is disabled, revert to WordPress profile
 		if ( !bp_is_active( 'xprofile' ) ) {
 
-			// Define local variable
-			$sub_nav = array();
-
 			// Fallback values if xprofile is disabled
 			if ( ! isset( $bp->core->profile ) ) {
 				$bp->core->profile = new stdClass;
@@ -236,14 +254,13 @@ class BP_Core extends BP_Component {
 }
 
 /**
- * Setup the BuddyPress Core component
+ * Set up the BuddyPress Core component.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @global BuddyPress $bp
+ * @global BuddyPress $bp BuddyPress global settings object.
  */
 function bp_setup_core() {
-	global $bp;
-	$bp->core = new BP_Core();
+	buddypress()->core = new BP_Core();
 }
 add_action( 'bp_setup_components', 'bp_setup_core', 2 );
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-moderation.php b/wp-content/plugins/buddypress/bp-core/bp-core-moderation.php
index a090e2ff306706f7fdcf1ec199de8de101dad3f7..a1f2da1413424d1b7e44573066730d678992045e 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-moderation.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-moderation.php
@@ -1,10 +1,10 @@
 <?php
 /**
- * BuddyPress Moderation Functions
+ * BuddyPress Moderation Functions.
  *
  * @package BuddyPress
  * @subpackage Core
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 
 // Exit if accessed directly
@@ -13,18 +13,20 @@ if ( !defined( 'ABSPATH' ) ) exit;
 /** Moderation ****************************************************************/
 
 /**
- * Check for flooding
+ * Check for flooding.
  *
  * Check to make sure that a user is not making too many posts in a short amount
  * of time.
  *
- * @param int $user_id User id to check for flood
- * @return bool True if there is no flooding, true if there is
- * @since BuddyPress (1.6)
- * @uses current_user_can() To check if the current user can throttle
- * @uses bp_get_option() To get the throttle time
- * @uses get_transient() To get the last posted transient of the ip
- * @uses get_user_meta() To get the last posted meta of the user
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses current_user_can() To check if the current user can throttle.
+ * @uses bp_get_option() To get the throttle time.
+ * @uses get_transient() To get the last posted transient of the ip.
+ * @uses get_user_meta() To get the last posted meta of the user.
+ *
+ * @param int $user_id User id to check for flood.
+ * @return bool True if there is no flooding, false if there is.
  */
 function bp_core_check_for_flood( $user_id = 0 ) {
 
@@ -44,16 +46,18 @@ function bp_core_check_for_flood( $user_id = 0 ) {
 }
 
 /**
- * Check for moderation keys and too many links
+ * Check for moderation keys and too many links.
+ *
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses bp_current_author_ip() To get current user IP address.
+ * @uses bp_current_author_ua() To get current user agent.
+ * @uses bp_current_user_can() Allow super admins to bypass blacklist.
  *
- * @param int $user_id Topic or reply author ID
- * @param string $title The title of the content
- * @param string $content The content being posted
- * @return bool True if test is passed, false if fail
- * @since BuddyPress (1.6)
- * @uses bp_current_author_ip() To get current user IP address
- * @uses bp_current_author_ua() To get current user agent
- * @uses bp_current_user_can() Allow super admins to bypass blacklist
+ * @param int $user_id Topic or reply author ID.
+ * @param string $title The title of the content.
+ * @param string $content The content being posted.
+ * @return bool True if test is passed, false if fail.
  */
 function bp_core_check_for_moderation( $user_id = 0, $title = '', $content = '' ) {
 
@@ -150,16 +154,18 @@ function bp_core_check_for_moderation( $user_id = 0, $title = '', $content = ''
 }
 
 /**
- * Checks for blocked keys
+ * Check for blocked keys.
  *
- * @param int $user_id Topic or reply author ID
- * @param string $title The title of the content
- * @param string $content The content being posted
- * @return bool True if test is passed, false if fail
- * @uses bp_current_author_ip() To get current user IP address
- * @uses bp_current_author_ua() To get current user agent
- * @uses bp_current_user_can() Allow super admins to bypass blacklist
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses bp_current_author_ip() To get current user IP address.
+ * @uses bp_current_author_ua() To get current user agent.
+ * @uses bp_current_user_can() Allow super admins to bypass blacklist.
+ *
+ * @param int $user_id Topic or reply author ID.
+ * @param string $title The title of the content.
+ * @param string $content The content being posted.
+ * @return bool True if test is passed, false if fail.
  */
 function bp_core_check_for_blacklist( $user_id = 0, $title = '', $content = '' ) {
 
@@ -238,10 +244,11 @@ function bp_core_check_for_blacklist( $user_id = 0, $title = '', $content = '' )
 }
 
 /**
- * Get the current-user IP address
+ * Get the current user's IP address.
  *
- * @return string
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @return string IP address.
  */
 function bp_core_current_user_ip() {
 	$retval = preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] );
@@ -250,10 +257,11 @@ function bp_core_current_user_ip() {
 }
 
 /**
- * Get the current-user user-agent
+ * Get the current user's user-agent.
+ *
+ * @since BuddyPress (1.6.0)
  *
- * @return string
- * @since BuddyPress (1.6)
+ * @return string User agent string.
  */
 function bp_core_current_user_ua() {
 
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-options.php b/wp-content/plugins/buddypress/bp-core/bp-core-options.php
index c015c5b19de797b4e996dbfdcc5d76a612da14c1..580ceb10b3cc803db24dd06f21f504efd8fa6d6e 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-options.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-options.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Options
+ * BuddyPress Options.
  *
  * @package BuddyPress
  * @subpackage Options
@@ -11,11 +11,11 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Get the default site options and their values
+ * Get the default site options and their values.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @return array Filtered option names and values
+ * @return array Filtered option names and values.
  */
 function bp_get_default_options() {
 
@@ -76,26 +76,44 @@ function bp_get_default_options() {
 		// Users from all sites can post
 		'_bp_enable_akismet'              => true,
 
+		/** Activity HeartBeat ************************************************/
+
+		// HeartBeat is on to refresh activities
+		'_bp_enable_heartbeat_refresh'    => true,
+
 		/** BuddyBar **********************************************************/
 
 		// Force the BuddyBar
-		'_bp_force_buddybar'              => false
+		'_bp_force_buddybar'              => false,
+
+		/** Legacy theme *********************************************/
+
+		// Whether to register the bp-default themes directory
+		'_bp_retain_bp_default'           => false,
+
+		/** Widgets **************************************************/
+		'widget_bp_core_login_widget'                => false,
+		'widget_bp_core_members_widget'              => false,
+		'widget_bp_core_whos_online_widget'          => false,
+		'widget_bp_core_recently_active_widget'      => false,
+		'widget_bp_groups_widget'                    => false,
+		'widget_bp_messages_sitewide_notices_widget' => false,
 	);
 
 	return apply_filters( 'bp_get_default_options', $options );
 }
 
 /**
- * Add default options
+ * Add default options when BuddyPress is first activated.
  *
- * Hooked to bp_activate, it is only called once when BuddyPress is activated.
- * This is non-destructive, so existing settings will not be overridden.
+ * Only called once when BuddyPress is activated.
+ * Non-destructive, so existing settings will not be overridden.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @uses bp_get_default_options() To get default options
- * @uses add_option() Adds default options
- * @uses do_action() Calls 'bp_add_options'
+ * @uses bp_get_default_options() To get default options.
+ * @uses add_option() Adds default options.
+ * @uses do_action() Calls 'bp_add_options'.
  */
 function bp_add_options() {
 
@@ -103,24 +121,27 @@ function bp_add_options() {
 	$options = bp_get_default_options();
 
 	// Add default options
-	foreach ( $options as $key => $value )
-		add_option( $key, $value );
+	foreach ( $options as $key => $value ) {
+		bp_add_option( $key, $value );
+	}
 
 	// Allow previously activated plugins to append their own options.
 	do_action( 'bp_add_options' );
 }
 
 /**
- * Delete default options
+ * Delete default options.
  *
  * Hooked to bp_uninstall, it is only called once when BuddyPress is uninstalled.
  * This is destructive, so existing settings will be destroyed.
  *
- * @since BuddyPress (1.6)
+ * Currently unused.
  *
- * @uses bp_get_default_options() To get default options
- * @uses delete_option() Removes default options
- * @uses do_action() Calls 'bp_delete_options'
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses bp_get_default_options() To get default options.
+ * @uses delete_option() Removes default options.
+ * @uses do_action() Calls 'bp_delete_options'.
  */
 function bp_delete_options() {
 
@@ -136,14 +157,15 @@ function bp_delete_options() {
 }
 
 /**
- * Add filters to each BuddyPress option and allow them to be overloaded from
- * inside the $bp->options array.
+ * Add filters to each BP option, allowing them to be overloaded from inside the $bp->options array.
  *
- * @since BuddyPress (1.6)
+ * Currently unused.
  *
- * @uses bp_get_default_options() To get default options
- * @uses add_filter() To add filters to 'pre_option_{$key}'
- * @uses do_action() Calls 'bp_add_option_filters'
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses bp_get_default_options() To get default options.
+ * @uses add_filter() To add filters to 'pre_option_{$key}'.
+ * @uses do_action() Calls 'bp_add_option_filters'.
  */
 function bp_setup_option_filters() {
 
@@ -159,8 +181,9 @@ function bp_setup_option_filters() {
 }
 
 /**
- * Filter default options and allow them to be overloaded from inside the
- * $bp->options array.
+ * Filter default options and allow them to be overloaded from inside the $bp->options array.
+ *
+ * Currently unused.
  *
  * @since BuddyPress (1.6)
  *
@@ -186,68 +209,86 @@ function bp_pre_get_option( $value = false ) {
 }
 
 /**
- * Retrieve an option
+ * Retrieve an option.
  *
- * This is a wrapper for get_blog_option(), which in turn stores settings data (such as bp-pages)
- * on the appropriate blog, given your current setup.
+ * This is a wrapper for {@link get_blog_option()}, which in turn stores settings data
+ * (such as bp-pages) on the appropriate blog, given your current setup.
  *
  * The 'bp_get_option' filter is primarily for backward-compatibility.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_root_blog_id()
- * @param string $option_name The option to be retrieved
- * @param string $default Optional. Default value to be returned if the option isn't set
- * @return mixed The value for the option
+ *
+ * @param string $option_name The option to be retrieved.
+ * @param string $default Optional. Default value to be returned if the option
+ *        isn't set. See {@link get_blog_option()}.
+ * @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 );
-
 	return apply_filters( 'bp_get_option', $value );
 }
 
 /**
- * Save an option
+ * Add an option.
  *
- * This is a wrapper for update_blog_option(), which in turn stores settings data (such as bp-pages)
- * on the appropriate blog, given your current setup.
+ * This is a wrapper for {@link add_blog_option()}, which in turn stores
+ * settings data on the appropriate blog, given your current setup.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $option_name The option key to be set.
+ * @param mixed $value The value to be set.
+ */
+function bp_add_option( $option_name, $value ) {
+	return add_blog_option( bp_get_root_blog_id(), $option_name, $value );
+}
+
+/**
+ * Save an option.
+ *
+ * This is a wrapper for {@link update_blog_option()}, which in turn stores
+ * settings data (such as bp-pages) on the appropriate blog, given your current
+ * setup.
+ *
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_root_blog_id()
- * @param string $option_name The option key to be set
- * @param string $value The value to be set
+ *
+ * @param string $option_name The option key to be set.
+ * @param string $value The value to be set.
  */
 function bp_update_option( $option_name, $value ) {
 	update_blog_option( bp_get_root_blog_id(), $option_name, $value );
 }
 
 /**
- * Delete an option
+ * Delete an option.
  *
- * This is a wrapper for delete_blog_option(), which in turn deletes settings data (such as
- * bp-pages) on the appropriate blog, given your current setup.
+ * This is a wrapper for {@link delete_blog_option()}, which in turn deletes
+ * settings data (such as bp-pages) on the appropriate blog, given your current
+ * setup.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_root_blog_id()
- * @param string $option_name The option key to be set
+ *
+ * @param string $option_name The option key to be deleted.
  */
 function bp_delete_option( $option_name ) {
 	delete_blog_option( bp_get_root_blog_id(), $option_name );
 }
 
 /**
- * When switching from single to multisite we need to copy blog options to
- * site options.
+ * Copy BP options from a single site to multisite config.
+ *
+ * Run when switching from single to multisite and we need to copy blog options
+ * to site options.
  *
- * This function is no longer used
+ * This function is no longer used.
  *
- * @package BuddyPress Core
- * @deprecated Since BuddyPress (1.6)
+ * @deprecated 1.6.0
  */
 function bp_core_activate_site_options( $keys = array() ) {
 	global $bp;
@@ -274,12 +315,15 @@ function bp_core_activate_site_options( $keys = array() ) {
 }
 
 /**
+ * Fetch global BP options.
+ *
  * BuddyPress uses common options to store configuration settings. Many of these
  * settings are needed at run time. Instead of fetching them all and adding many
  * initial queries to each page load, let's fetch them all in one go.
  *
- * @package BuddyPress Core
- * @todo Use settings API and audit these methods
+ * @todo Use settings API and audit these methods.
+ *
+ * @return array $root_blog_options_meta List of options.
  */
 function bp_core_get_root_options() {
 	global $wpdb;
@@ -291,80 +335,89 @@ function bp_core_get_root_options() {
 	$root_blog_option_keys               = array_keys( $root_blog_options );
 
 	// Do some magic to get all the root blog options in 1 swoop
-	$blog_options_keys      = "'" . join( "', '", (array) $root_blog_option_keys ) . "'";
-	$blog_options_table	    = bp_is_multiblog_mode() ? $wpdb->options : $wpdb->get_blog_prefix( bp_get_root_blog_id() ) . 'options';
-	$blog_options_query     = "SELECT option_name AS name, option_value AS value FROM {$blog_options_table} WHERE option_name IN ( {$blog_options_keys} )";
-	$root_blog_options_meta = $wpdb->get_results( $blog_options_query );
-
-	// On Multisite installations, some options must always be fetched from sitemeta
-	if ( is_multisite() ) {
-		$network_options = apply_filters( 'bp_core_network_options', array(
-			'tags_blog_id'       => '0',
-			'sitewide_tags_blog' => '',
-			'registration'       => '0',
-			'fileupload_maxk'    => '1500'
-		) );
-
-		$current_site           = get_current_site();
-		$network_option_keys    = array_keys( $network_options );
-		$sitemeta_options_keys  = "'" . join( "', '", (array) $network_option_keys ) . "'";
-		$sitemeta_options_query = $wpdb->prepare( "SELECT meta_key AS name, meta_value AS value FROM {$wpdb->sitemeta} WHERE meta_key IN ( {$sitemeta_options_keys} ) AND site_id = %d", $current_site->id );
-		$network_options_meta   = $wpdb->get_results( $sitemeta_options_query );
-
-		// Sitemeta comes second in the merge, so that network 'registration' value wins
-		$root_blog_options_meta = array_merge( $root_blog_options_meta, $network_options_meta );
-	}
+	// Check cache first - We cache here instead of using the standard WP
+	// settings cache because the current blog may not be the root blog,
+	// and it's not practical to access the cache across blogs
+	$root_blog_options_meta = wp_cache_get( 'root_blog_options', 'bp' );
+
+	if ( false === $root_blog_options_meta ) {
+		$blog_options_keys      = "'" . join( "', '", (array) $root_blog_option_keys ) . "'";
+		$blog_options_table	    = bp_is_multiblog_mode() ? $wpdb->options : $wpdb->get_blog_prefix( bp_get_root_blog_id() ) . 'options';
+		$blog_options_query     = "SELECT option_name AS name, option_value AS value FROM {$blog_options_table} WHERE option_name IN ( {$blog_options_keys} )";
+		$root_blog_options_meta = $wpdb->get_results( $blog_options_query );
+
+		// On Multisite installations, some options must always be fetched from sitemeta
+		if ( is_multisite() ) {
+			$network_options = apply_filters( 'bp_core_network_options', array(
+				'tags_blog_id'       => '0',
+				'sitewide_tags_blog' => '',
+				'registration'       => '0',
+				'fileupload_maxk'    => '1500'
+			) );
+
+			$current_site           = get_current_site();
+			$network_option_keys    = array_keys( $network_options );
+			$sitemeta_options_keys  = "'" . join( "', '", (array) $network_option_keys ) . "'";
+			$sitemeta_options_query = $wpdb->prepare( "SELECT meta_key AS name, meta_value AS value FROM {$wpdb->sitemeta} WHERE meta_key IN ( {$sitemeta_options_keys} ) AND site_id = %d", $current_site->id );
+			$network_options_meta   = $wpdb->get_results( $sitemeta_options_query );
+
+			// Sitemeta comes second in the merge, so that network 'registration' value wins
+			$root_blog_options_meta = array_merge( $root_blog_options_meta, $network_options_meta );
+		}
 
-	// Missing some options, so do some one-time fixing
-	if ( empty( $root_blog_options_meta ) || ( count( $root_blog_options_meta ) < count( $root_blog_option_keys ) ) ) {
+		// Missing some options, so do some one-time fixing
+		if ( empty( $root_blog_options_meta ) || ( count( $root_blog_options_meta ) < count( $root_blog_option_keys ) ) ) {
 
-		// Get a list of the keys that are already populated
-		$existing_options = array();
-		foreach( $root_blog_options_meta as $already_option ) {
-			$existing_options[$already_option->name] = $already_option->value;
-		}
+			// Get a list of the keys that are already populated
+			$existing_options = array();
+			foreach( $root_blog_options_meta as $already_option ) {
+				$existing_options[$already_option->name] = $already_option->value;
+			}
 
-		// Unset the query - We'll be resetting it soon
-		unset( $root_blog_options_meta );
+			// Unset the query - We'll be resetting it soon
+			unset( $root_blog_options_meta );
 
-		// Loop through options
-		foreach ( $root_blog_options as $old_meta_key => $old_meta_default ) {
-			// Clear out the value from the last time around
-			unset( $old_meta_value );
+			// Loop through options
+			foreach ( $root_blog_options as $old_meta_key => $old_meta_default ) {
+				// Clear out the value from the last time around
+				unset( $old_meta_value );
 
-			if ( isset( $existing_options[$old_meta_key] ) ) {
-				continue;
-			}
+				if ( isset( $existing_options[$old_meta_key] ) ) {
+					continue;
+				}
 
-			// Get old site option
-			if ( is_multisite() )
-				$old_meta_value = get_site_option( $old_meta_key );
+				// Get old site option
+				if ( is_multisite() )
+					$old_meta_value = get_site_option( $old_meta_key );
 
-			// No site option so look in root blog
-			if ( empty( $old_meta_value ) )
-				$old_meta_value = bp_get_option( $old_meta_key, $old_meta_default );
+				// No site option so look in root blog
+				if ( empty( $old_meta_value ) )
+					$old_meta_value = bp_get_option( $old_meta_key, $old_meta_default );
 
-			// Update the root blog option
-			bp_update_option( $old_meta_key, $old_meta_value );
+				// Update the root blog option
+				bp_update_option( $old_meta_key, $old_meta_value );
 
-			// Update the global array
-			$root_blog_options_meta[$old_meta_key] = $old_meta_value;
-		}
+				// Update the global array
+				$root_blog_options_meta[$old_meta_key] = $old_meta_value;
+			}
+
+			$root_blog_options_meta = array_merge( $root_blog_options_meta, $existing_options );
+			unset( $existing_options );
 
-		$root_blog_options_meta = array_merge( $root_blog_options_meta, $existing_options );
-		unset( $existing_options );
+		// We're all matched up
+		} else {
+			// Loop through our results and make them usable
+			foreach ( $root_blog_options_meta as $root_blog_option )
+				$root_blog_options[$root_blog_option->name] = $root_blog_option->value;
 
-	// We're all matched up
-	} else {
-		// Loop through our results and make them usable
-		foreach ( $root_blog_options_meta as $root_blog_option )
-			$root_blog_options[$root_blog_option->name] = $root_blog_option->value;
+			// Copy the options no the return val
+			$root_blog_options_meta = $root_blog_options;
 
-		// Copy the options no the return val
-		$root_blog_options_meta = $root_blog_options;
+			// Clean up our temporary copy
+			unset( $root_blog_options );
+		}
 
-		// Clean up our temporary copy
-		unset( $root_blog_options );
+		wp_cache_set( 'root_blog_options', $root_blog_options_meta, 'bp' );
 	}
 
 	return apply_filters( 'bp_core_get_root_options', $root_blog_options_meta );
@@ -375,12 +428,13 @@ function bp_core_get_root_options() {
 /**
  * Is profile sycing disabled?
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional.Default value true
+ * @uses bp_get_option() To get the profile sync option.
  *
- * @uses bp_get_option() To get the profile sync option
- * @return bool Is profile sync enabled or not
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if profile sync is enabled, otherwise false.
  */
 function bp_disable_profile_sync( $default = true ) {
 	return (bool) apply_filters( 'bp_disable_profile_sync', (bool) bp_get_option( 'bp-disable-profile-sync', $default ) );
@@ -389,12 +443,14 @@ function bp_disable_profile_sync( $default = true ) {
 /**
  * Is the Toolbar hidden for logged out users?
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional.Default value true
+ * @uses bp_get_option() To get the logged out Toolbar option.
  *
- * @uses bp_get_option() To get the logged out Toolbar option
- * @return bool Is logged out Toolbar enabled or not
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if the admin bar should be hidden for logged-out users,
+ *         otherwise false.
  */
 function bp_hide_loggedout_adminbar( $default = true ) {
 	return (bool) apply_filters( 'bp_hide_loggedout_adminbar', (bool) bp_get_option( 'hide-loggedout-adminbar', $default ) );
@@ -403,12 +459,13 @@ function bp_hide_loggedout_adminbar( $default = true ) {
 /**
  * Are members able to upload their own avatars?
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional. Default value true
+ * @uses bp_get_option() To get the avatar uploads option.
  *
- * @uses bp_get_option() To get the avatar uploads option
- * @return bool Are avatar uploads allowed?
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if avatar uploads are disabled, otherwise false.
  */
 function bp_disable_avatar_uploads( $default = true ) {
 	return (bool) apply_filters( 'bp_disable_avatar_uploads', (bool) bp_get_option( 'bp-disable-avatar-uploads', $default ) );
@@ -417,12 +474,14 @@ function bp_disable_avatar_uploads( $default = true ) {
 /**
  * Are members able to delete their own accounts?
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional. Default value
+ * @uses bp_get_option() To get the account deletion option.
  *
- * @uses bp_get_option() To get the account deletion option
- * @return bool Is account deletion allowed?
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if users are able to delete their own accounts, otherwise
+ *         false.
  */
 function bp_disable_account_deletion( $default = false ) {
 	return apply_filters( 'bp_disable_account_deletion', (bool) bp_get_option( 'bp-disable-account-deletion', $default ) );
@@ -431,12 +490,15 @@ function bp_disable_account_deletion( $default = false ) {
 /**
  * Are blog and forum activity stream comments disabled?
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @todo split and move into blog and forum components.
+ * @uses bp_get_option() To get the blog/forum comments option.
  *
- * @param bool $default Optional. Default value false
- * @todo split and move into blog and forum components
- * @uses bp_get_option() To get the blog/forum comments option
- * @return bool Is blog/forum comments allowed?
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: false.
+ * @return bool True if activity comments are disabled for blog and forum
+ *         items, otherwise false.
  */
 function bp_disable_blogforum_comments( $default = false ) {
 	return (bool) apply_filters( 'bp_disable_blogforum_comments', (bool) bp_get_option( 'bp-disable-blogforum-comments', $default ) );
@@ -445,93 +507,113 @@ function bp_disable_blogforum_comments( $default = false ) {
 /**
  * Is group creation turned off?
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional. Default value true
+ * @todo Move into groups component.
+ * @uses bp_get_option() To get the group creation.
  *
- * @todo Move into groups component
- * @uses bp_get_option() To get the group creation
- * @return bool Allow group creation?
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if group creation is restricted, otherwise false.
  */
 function bp_restrict_group_creation( $default = true ) {
 	return (bool) apply_filters( 'bp_restrict_group_creation', (bool) bp_get_option( 'bp_restrict_group_creation', $default ) );
 }
 
 /**
- * Have we migrated to using the WordPress Toolbar?
+ * Should the old BuddyBar be forced in place of the WP admin bar?
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional. Default value true
+ * @uses bp_get_option() To get the BuddyBar option.
  *
- * @todo Move into groups component
- * @uses bp_get_option() To get the WP editor option
- * @return bool Use WP editor?
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if the BuddyBar should be forced on, otherwise false.
  */
 function bp_force_buddybar( $default = true ) {
 	return (bool) apply_filters( 'bp_force_buddybar', (bool) bp_get_option( '_bp_force_buddybar', $default ) );
 }
 
 /**
- * Output the group forums root parent forum id
+ * Output the group forums root parent forum id.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional. Default value
+ * @param bool $default Optional. Default: '0'.
  */
 function bp_group_forums_root_id( $default = '0' ) {
 	echo bp_get_group_forums_root_id( $default );
 }
 	/**
-	 * Return the group forums root parent forum id
+	 * Return the group forums root parent forum id.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @param bool $default Optional. Default value 0
+	 * @uses bp_get_option() To get the root forum ID from the database.
 	 *
-	 * @uses bp_get_option() To get the maximum title length
-	 * @return int Is anonymous posting allowed?
+	 * @param bool $default Optional. Default: '0'.
+	 * @return int The ID of the group forums root forum.
 	 */
 	function bp_get_group_forums_root_id( $default = '0' ) {
 		return (int) apply_filters( 'bp_get_group_forums_root_id', (int) bp_get_option( '_bp_group_forums_root_id', $default ) );
 	}
 
 /**
- * Checks if BuddyPress Group Forums are enabled
+ * Check whether BuddyPress Group Forums are enabled.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional. Default value true
+ * @uses bp_get_option() To get the group forums option.
  *
- * @uses bp_get_option() To get the group forums option
- * @return bool Is group forums enabled or not
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if group forums are active, otherwise false.
  */
 function bp_is_group_forums_active( $default = true ) {
 	return (bool) apply_filters( 'bp_is_group_forums_active', (bool) bp_get_option( '_bp_enable_group_forums', $default ) );
 }
 
 /**
- * Checks if Akismet is enabled
+ * Check whether Akismet is enabled.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @param bool $default Optional. Default value true
+ * @uses bp_get_option() To get the Akismet option.
  *
- * @uses bp_get_option() To get the Akismet option
- * @return bool Is Akismet enabled or not
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if Akismet is enabled, otherwise false.
  */
 function bp_is_akismet_active( $default = true ) {
 	return (bool) apply_filters( 'bp_is_akismet_active', (bool) bp_get_option( '_bp_enable_akismet', $default ) );
 }
 
 /**
- * Get the current theme package ID
+ * Check whether Activity Heartbeat refresh is enabled.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @uses bp_get_option() To get the Heartbeat option.
+ *
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: true.
+ * @return bool True if Heartbeat refresh is enabled, otherwise false.
+ */
+function bp_is_activity_heartbeat_active( $default = true ) {
+	return (bool) apply_filters( 'bp_is_activity_heartbeat_active', (bool) bp_get_option( '_bp_enable_heartbeat_refresh', $default ) );
+}
+
+/**
+ * Get the current theme package ID.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
+ * @uses get_option() To get the theme package option.
  *
- * @param string $default Optional. Default value 'default'
- * @uses get_option() To get the subtheme option
- * @return string ID of the subtheme
+ * @param bool $default Optional. Fallback value if not found in the database.
+ *        Default: 'legacy'.
+ * @return string ID of the theme package.
  */
 function bp_get_theme_package_id( $default = 'legacy' ) {
 	return apply_filters( 'bp_get_theme_package_id', bp_get_option( '_bp_theme_package_id', $default ) );
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-template-loader.php b/wp-content/plugins/buddypress/bp-core/bp-core-template-loader.php
index 7887169a66f271adbcdcd12186476e1655242d46..85b1a90876bb8b99d58adca71ffc03b4f21cfeb4 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-template-loader.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-template-loader.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Template Functions
+ * BuddyPress Template Functions.
  *
  * This file contains functions necessary to mirror the WordPress core template
  * loading process. Many of those functions are not filterable, and even then
@@ -15,15 +15,19 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Adds BuddyPress theme support to any active WordPress theme
+ * Get a BuddyPress template part for display in a theme.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @param string $slug
- * @param string $name Optional. Default null
  * @uses bp_locate_template()
  * @uses load_template()
  * @uses get_template_part()
+ *
+ * @param string $slug Template part slug. Used to generate filenames, eg
+ *        'friends' for 'friends.php'.
+ * @param string $name Optional. Template part name. Used to generate
+ *        secondary filenames, eg 'personal' for 'activity-personal.php'.
+ * @return string Path to located template. See {@link bp_locate_template()}.
  */
 function bp_get_template_part( $slug, $name = null ) {
 
@@ -50,12 +54,13 @@ function bp_get_template_part( $slug, $name = null ) {
  * inherit from a parent theme can just overload one file. If the template is
  * not found in either of those, it looks in the theme-compat folder last.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
  * @param string|array $template_names Template file(s) to search for, in order.
- * @param bool $load If true the template file will be loaded if it is found.
- * @param bool $require_once Whether to require_once or require. Default true.
- *                            Has no effect if $load is false.
+ * @param bool $load Optional. If true, the template file will be loaded when
+ *        found. If false, the path will be returned. Default: false.
+ * @param bool $require_once Optional. Whether to require_once or require. Has
+ *        no effect if $load is false. Default: true.
  * @return string The template filename if one is located.
  */
 function bp_locate_template( $template_names, $load = false, $require_once = true ) {
@@ -89,25 +94,40 @@ function bp_locate_template( $template_names, $load = false, $require_once = tru
 		}
 	}
 
+	/**
+	 * This action exists only to follow the standard BuddyPress coding convention,
+	 * and should not be used to short-circuit any part of the template locator.
+	 *
+	 * If you want to override a specific template part, please either filter
+	 * 'bp_get_template_part' or add a new location to the template stack.
+	 */
+	do_action( 'bp_locate_template', $located, $template_name, $template_names, $template_locations, $load, $require_once );
+
 	// Maybe load the template if one was located
-	if ( ( true == $load ) && !empty( $located ) )
+	$use_themes = defined( 'WP_USE_THEMES' ) && WP_USE_THEMES;
+	$doing_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
+	if ( ( $use_themes || $doing_ajax ) && ( true == $load ) && ! empty( $located ) ) {
 		load_template( $located, $require_once );
+	}
 
 	return $located;
 }
 
 /**
- * This is really cool. This function registers a new template stack location,
- * using WordPress's built in filters API.
+ * Register a new template stack location.
  *
  * This allows for templates to live in places beyond just the parent/child
  * relationship, to allow for custom template locations. Used in conjunction
  * with bp_locate_template(), this allows for easy template overrides.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @param string $location Callback function that returns the stack location
- * @param int $priority
+ * @todo Make 'callable' instead of 'function'.
+ *
+ * @param string $location Callback function that returns the stack location.
+ * @param int $priority Optional. The priority parameter as passed to
+ *        add_filter(). Default: 10.
+ * @return bool See {@link add_filter()}.
  */
 function bp_register_template_stack( $location_callback = '', $priority = 10 ) {
 
@@ -120,13 +140,16 @@ function bp_register_template_stack( $location_callback = '', $priority = 10 ) {
 }
 
 /**
- * Deregisters a previously registered template stack location.
+ * Deregister a previously registered template stack location.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @param string $location Callback function that returns the stack location
- * @param int $priority
  * @see bp_register_template_stack()
+ *
+ * @param string $location Callback function that returns the stack location.
+ * @param int $priority Optional. The priority parameter passed to
+ *        {@link bp_register_template_stack()}. Default: 10.
+ * @return bool See {@link remove_filter()}.
  */
 function bp_deregister_template_stack( $location_callback = '', $priority = 10 ) {
 
@@ -139,17 +162,19 @@ function bp_deregister_template_stack( $location_callback = '', $priority = 10 )
 }
 
 /**
- * Call the functions added to the 'bp_template_stack' filter hook, and return
+ * Get the "template stack", a list of registered directories where templates can be found.
+ *
+ * Calls the functions added to the 'bp_template_stack' filter hook, and return
  * an array of the template locations.
  *
  * @see bp_register_template_stack()
  *
- * @since BuddyPress (1.7)
- *
- * @global array $wp_filter Stores all of the filters
- * @global array $merged_filters Merges the filter hooks using this function.
- * @global array $wp_current_filter stores the list of current filters with the current one last
+ * @since BuddyPress (1.7.0)
  *
+ * @global array $wp_filter Stores all of the filters.
+ * @global array $merged_filters Merges the filter hooks using this function..
+ * @global array $wp_current_filter stores the list of current filters with
+ *         the current one last.
  * @return array The filtered value after all hooked functions are applied to it.
  */
 function bp_get_template_stack() {
@@ -191,13 +216,17 @@ function bp_get_template_stack() {
 }
 
 /**
- * Get a template part in an output buffer, and return it
+ * Put a template part into an output buffer, and return it.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @see bp_get_template_part() for a description of $slug and $name params.
  *
- * @param string $slug
- * @param string $name
- * @return string
+ * @param string $slug See {@link bp_get_template_part()}.
+ * @param string $name See {@link bp_get_template_part()}.
+ * @param bool $echo If true, template content will be echoed. If false,
+ *        returned. Default: true.
+ * @return string|null If $echo, returns the template content.
  */
 function bp_buffer_template_part( $slug, $name = null, $echo = true ) {
 	ob_start();
@@ -222,20 +251,21 @@ function bp_buffer_template_part( $slug, $name = null, $echo = true ) {
 }
 
 /**
- * Retrieve path to a template
+ * Retrieve the path to a template.
  *
  * Used to quickly retrieve the path of a template without including the file
  * extension. It will also check the parent theme and theme-compat theme with
  * the use of {@link bp_locate_template()}. Allows for more generic template
  * locations without the use of the other get_*_template() functions.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @param string $type Filename without extension.
- * @param array $templates An optional list of template candidates
  * @uses bp_set_theme_compat_templates()
  * @uses bp_locate_template()
  * @uses bp_set_theme_compat_template()
+ *
+ * @param string $type Filename without extension.
+ * @param array $templates An optional list of template candidates.
  * @return string Full path to file.
  */
 function bp_get_query_template( $type, $templates = array() ) {
@@ -271,12 +301,12 @@ function bp_get_template_locations( $templates = array() ) {
 }
 
 /**
- * Add template locations to template files being searched for
+ * Add template locations to template files being searched for.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @param array $stacks
- * @return array()
+ * @param array $stacks Array of template locations.
+ * @return array() Array of all template locations registered so far.
  */
 function bp_add_template_stack_locations( $stacks = array() ) {
 	$retval = array();
@@ -293,9 +323,9 @@ function bp_add_template_stack_locations( $stacks = array() ) {
 }
 
 /**
- * Add checks for BuddyPress conditions to parse_query action
+ * Add checks for BuddyPress conditions to 'parse_query' action.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
  * @param WP_Query $posts_query
  */
@@ -318,7 +348,7 @@ function bp_parse_query( $posts_query ) {
 }
 
 /**
- * Possibly intercept the template being loaded
+ * Possibly intercept the template being loaded.
  *
  * Listens to the 'template_include' filter and waits for any BuddyPress specific
  * template condition to be met. If one is met and the template file exists,
@@ -327,11 +357,10 @@ function bp_parse_query( $posts_query ) {
  * Note that the _edit() checks are ahead of their counterparts, to prevent them
  * from being stomped on accident.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
  * @param string $template
- *
- * @return string The path to the template file that is being used
+ * @return string The path to the template file that is being used.
  */
 function bp_template_include_theme_supports( $template = '' ) {
 
@@ -348,11 +377,12 @@ function bp_template_include_theme_supports( $template = '' ) {
 }
 
 /**
- * Set the included template
+ * Set the included template.
  *
- * @since BuddyPress (1.8)
- * @param mixed $template Default false
- * @return mixed False if empty. Template name if template included
+ * @since BuddyPress (1.8.0)
+ *
+ * @param mixed $template Default: false.
+ * @return mixed False if empty. Template name if template included.
  */
 function bp_set_template_included( $template = false ) {
 	buddypress()->theme_compat->found_template = $template;
@@ -363,29 +393,41 @@ function bp_set_template_included( $template = false ) {
 /**
  * Is a BuddyPress template being included?
  *
- * @since BuddyPress (1.8)
- * @return bool True if yes, false if no
+ * @since BuddyPress (1.8.0)
+ * @return bool True if yes, false if no.
  */
 function bp_is_template_included() {
 	return ! empty( buddypress()->theme_compat->found_template );
 }
 
 /**
- * Attempt to load a custom BuddyPress functions file, similar to each themes
- * functions.php file.
+ * Attempt to load a custom BP functions file, similar to each themes functions.php file.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
  * @global string $pagenow
  * @uses bp_locate_template()
  */
 function bp_load_theme_functions() {
-	global $pagenow;
+	global $pagenow, $wp_query;
+
+	// do not load our custom BP functions file if theme compat is disabled
+	if ( ! bp_use_theme_compat_with_current_theme() ) {
+		return;
+	}
 
 	// Do not include on BuddyPress deactivation
 	if ( bp_is_deactivation() )
 		return;
 
+	// If the $wp_query global is empty (the main query has not been run,
+	// or has been reset), load_template() will fail at setting certain
+	// global values. This does not happen on a normal page load, but can
+	// cause problems when running automated tests
+	if ( ! is_a( $wp_query, 'WP_Query' ) ) {
+		return;
+	}
+
 	// Only include if not installing or if activating via wp-activate.php
 	if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) {
 		bp_locate_template( 'buddypress-functions.php', true );
@@ -393,12 +435,11 @@ function bp_load_theme_functions() {
 }
 
 /**
- * Get the templates to use as the endpoint for BuddyPress template parts
+ * Get the templates to use as the endpoint for BuddyPress template parts.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @uses apply_filters()
- * @return array Of possible root level wrapper template files
+ * @return array Array of possible root level wrapper template files.
  */
 function bp_get_theme_compat_templates() {
 	$templates = array(
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-template.php b/wp-content/plugins/buddypress/bp-core/bp-core-template.php
index 3c7757fb3bc4f1ede96910279788d5b3dc896704..de057015187c9074bb7428b475252a07835ebd8c 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-template.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-template.php
@@ -1,21 +1,31 @@
 <?php
+/**
+ * Core component template tag functions
+ *
+ * @package BuddyPress
+ * @subpackage TemplateFunctions
+ */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Uses the $bp->bp_options_nav global to render out the sub navigation for the current component.
- * Each component adds to its sub navigation array within its own setup_nav() function.
+ * Output the "options nav", the secondary-level single item navigation menu.
  *
- * This sub navigation array is the secondary level navigation, so for profile it contains:
+ * Uses the $bp->bp_options_nav global to render out the sub navigation for the
+ * current component. Each component adds to its sub navigation array within
+ * its own setup_nav() function.
+ *
+ * This sub navigation array is the secondary level navigation, so for profile
+ * it contains:
  *      [Public, Edit Profile, Change Avatar]
  *
- * The function will also analyze the current action for the current component to determine whether
- * or not to highlight a particular sub nav item.
+ * The function will also analyze the current action for the current component
+ * to determine whether or not to highlight a particular sub nav item.
  *
- * @package BuddyPress Core
- * @global BuddyPress $bp The one true BuddyPress instance
- * @uses bp_get_user_nav() Renders the navigation for a profile of a currently viewed user.
+ * @global BuddyPress $bp The one true BuddyPress instance.
+ * @uses bp_get_user_nav() Renders the navigation for a profile of a currently
+ *       viewed user.
  */
 function bp_get_options_nav() {
 	global $bp;
@@ -58,6 +68,12 @@ function bp_get_options_nav() {
 	}
 }
 
+/**
+ * Get the 'bp_options_title' property from the BP global.
+ *
+ * Not currently used in BuddyPress.
+ * @todo Deprecate.
+ */
 function bp_get_options_title() {
 	global $bp;
 
@@ -67,14 +83,46 @@ function bp_get_options_title() {
 	echo apply_filters( 'bp_get_options_title', esc_attr( $bp->bp_options_title ) );
 }
 
+/**
+ * Get the directory title for a component.
+ *
+ * Used for the <title> element and the page header on the component directory
+ * page.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return string
+ */
+function bp_get_directory_title( $component = '' ) {
+	$title = '';
+
+	// Use the string provided by the component
+	if ( ! empty( buddypress()->{$component}->directory_title ) ) {
+		$title = buddypress()->{$component}->directory_title;
+
+	// If none is found, concatenate
+	} else if ( isset( buddypress()->{$component}->name ) ) {
+		$title = sprintf( __( '%s Directory', 'buddypress' ), buddypress()->{$component}->name );
+	}
+
+	return apply_filters( 'bp_get_directory_title', $title, $component );
+}
+
 /** Avatars *******************************************************************/
 
 /**
- * Check to see if there is an options avatar. An options avatar is an avatar for something
- * like a group, or a friend. Basically an avatar that appears in the sub nav options bar.
+ * Check to see if there is an options avatar.
+ *
+ * An options avatar is an avatar for something like a group, or a friend.
+ * Basically an avatar that appears in the sub nav options bar.
  *
- * @package BuddyPress Core
- * @global BuddyPress $bp The one true BuddyPress instance
+ * Not currently used in BuddyPress.
+ *
+ * @global BuddyPress $bp The one true BuddyPress instance.
+ * @todo Deprecate.
+ *
+ * @return bool Returns true if an options avatar has been set, otherwise
+ *         false.
  */
 function bp_has_options_avatar() {
 	global $bp;
@@ -85,12 +133,26 @@ function bp_has_options_avatar() {
 	return true;
 }
 
+/**
+ * Output the options avatar.
+ *
+ * Not currently used in BuddyPress.
+ *
+ * @todo Deprecate.
+ */
 function bp_get_options_avatar() {
 	global $bp;
 
 	echo apply_filters( 'bp_get_options_avatar', $bp->bp_options_avatar );
 }
 
+/**
+ * Output a comment author's avatar.
+ *
+ * Not currently used in BuddyPress.
+ *
+ * @todo Deprecate.
+ */
 function bp_comment_author_avatar() {
 	global $comment;
 
@@ -100,6 +162,13 @@ function bp_comment_author_avatar() {
 		get_avatar();
 }
 
+/**
+ * Output a post author's avatar.
+ *
+ * Not currently used in BuddyPress.
+ *
+ * @todo Deprecate.
+ */
 function bp_post_author_avatar() {
 	global $post;
 
@@ -109,9 +178,18 @@ function bp_post_author_avatar() {
 		get_avatar();
 }
 
+/**
+ * Output the current avatar upload step.
+ */
 function bp_avatar_admin_step() {
 	echo bp_get_avatar_admin_step();
 }
+	/**
+	 * Return the current avatar upload step.
+	 *
+	 * @return string The current avatar upload step. Returns 'upload-image'
+	 *         if none is found.
+	 */
 	function bp_get_avatar_admin_step() {
 		global $bp;
 
@@ -123,9 +201,17 @@ function bp_avatar_admin_step() {
 		return apply_filters( 'bp_get_avatar_admin_step', $step );
 	}
 
+/**
+ * Output the URL of the avatar to crop.
+ */
 function bp_avatar_to_crop() {
 	echo bp_get_avatar_to_crop();
 }
+	/**
+	 * Return the URL of the avatar to crop.
+	 *
+	 * @return string URL of the avatar awaiting cropping.
+	 */
 	function bp_get_avatar_to_crop() {
 		global $bp;
 
@@ -137,15 +223,30 @@ function bp_avatar_to_crop() {
 		return apply_filters( 'bp_get_avatar_to_crop', $url );
 	}
 
+/**
+ * Output the relative file path to the avatar to crop.
+ */
 function bp_avatar_to_crop_src() {
 	echo bp_get_avatar_to_crop_src();
 }
+	/**
+	 * Return the relative file path to the avatar to crop.
+	 *
+	 * @return string Relative file path to the avatar.
+	 */
 	function bp_get_avatar_to_crop_src() {
 		global $bp;
 
 		return apply_filters( 'bp_get_avatar_to_crop_src', str_replace( WP_CONTENT_DIR, '', $bp->avatar_admin->image->dir ) );
 	}
 
+/**
+ * Output the avatar cropper <img> markup.
+ *
+ * No longer used in BuddyPress.
+ *
+ * @todo Deprecate.
+ */
 function bp_avatar_cropper() {
 	global $bp;
 
@@ -153,20 +254,32 @@ function bp_avatar_cropper() {
 }
 
 /**
- * Echoes bp_get_site_name()
+ * Output the name of the BP site. Used in RSS headers.
  */
 function bp_site_name() {
 	echo bp_get_site_name();
 }
 	/**
-	 * Returns the name of the BP site. Used in RSS headers
+	 * Returns the name of the BP site. Used in RSS headers.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 */
 	function bp_get_site_name() {
 		return apply_filters( 'bp_site_name', get_bloginfo( 'name', 'display' ) );
 	}
 
+/**
+ * Format a date.
+ *
+ * @param int $time The UNIX timestamp to be formatted.
+ * @param bool $just_date Optional. True to return only the month + day, false
+ *        to return month, day, and time. Default: false.
+ * @param bool $localize_time Optional. True to display in local time, false to
+ *        leave in GMT. Default: true.
+ * @return string|bool $localize_time Optional. A string representation of
+ *         $time, in the format "January 1, 2010 at 9:50pm" (or whatever your
+ *         'date_format' and 'time_format' settings are). False on failure.
+ */
 function bp_format_time( $time, $just_date = false, $localize_time = true ) {
 	if ( !isset( $time ) || !is_numeric( $time ) )
 		return false;
@@ -194,6 +307,24 @@ function bp_format_time( $time, $just_date = false, $localize_time = true ) {
 	return apply_filters( 'bp_format_time', $date );
 }
 
+/**
+ * Select between two dynamic strings, according to context.
+ *
+ * This function can be used in cases where a phrase used in a template will
+ * differ for a user looking at his own profile and a user looking at another
+ * user's profile (eg, "My Friends" and "Joe's Friends"). Pass both versions
+ * of the phrase, and bp_word_or_name() will detect which is appropriate, and
+ * do the necessary argument swapping for dynamic phrases.
+ *
+ * @param string $youtext The "you" version of the phrase (eg "Your Friends").
+ * @param string $nametext The other-user version of the phrase. Should be in
+ *        a format appropriate for sprintf() - use %s in place of the displayed
+ *        user's name (eg "%'s Friends").
+ * @param bool $capitalize Optional. Force into title case. Default: true.
+ * @param bool $echo Optional. True to echo the results, false to return them.
+ *        Default: true.
+ * @return string|null If ! $echo, returns the appropriate string.
+ */
 function bp_word_or_name( $youtext, $nametext, $capitalize = true, $echo = true ) {
 
 	if ( !empty( $capitalize ) )
@@ -217,7 +348,13 @@ function bp_word_or_name( $youtext, $nametext, $capitalize = true, $echo = true
 	}
 }
 
-
+/**
+ * Do the 'bp_styles' action, and call wp_print_styles().
+ *
+ * No longer used in BuddyPress.
+ *
+ * @todo Deprecate.
+ */
 function bp_styles() {
 	do_action( 'bp_styles' );
 	wp_print_styles();
@@ -225,15 +362,21 @@ function bp_styles() {
 
 /** Search Form ***************************************************************/
 
+/**
+ * Return the "action" attribute for search forms.
+ *
+ * @return string URL action attribute for search forms, eg example.com/search/.
+ */
 function bp_search_form_action() {
 	return apply_filters( 'bp_search_form_action', trailingslashit( bp_get_root_domain() . '/' . bp_get_search_slug() ) );
 }
 
 /**
- * Generates the basic search form as used in BP-Default's header.
+ * Generate the basic search form as used in BP-Default's header.
+ *
+ * @since BuddyPress (1.0.0)
  *
- * @return string HTML <select> element
- * @since BuddyPress (1.0)
+ * @return string HTML <select> element.
  */
 function bp_search_form_type_select() {
 
@@ -267,15 +410,25 @@ function bp_search_form_type_select() {
 }
 
 /**
- * Get the default text for the search box for a given component.
+ * Output the default text for the search box for a given component.
  *
- * @global object $bp BuddyPress global settings
- * @return string
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @see bp_get_search_default_text()
+ *
+ * @param string $component See {@link bp_get_search_default_text()}.
  */
 function bp_search_default_text( $component = '' ) {
 	echo bp_get_search_default_text( $component );
 }
+	/**
+	 * Return the default text for the search box for a given component.
+	 *
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @param string $component Component name. Default: current component.
+	 * @return string Placeholder text for search field.
+	 */
 	function bp_get_search_default_text( $component = '' ) {
 		global $bp;
 
@@ -302,54 +455,53 @@ function bp_search_default_text( $component = '' ) {
 		return apply_filters( 'bp_get_search_default_text', $default_text, $component );
 	}
 
+/**
+ * Fire the 'bp_custom_profile_boxes' action.
+ *
+ * No longer used in BuddyPress.
+ *
+ * @todo Deprecate.
+ */
 function bp_custom_profile_boxes() {
 	do_action( 'bp_custom_profile_boxes' );
 }
 
+/**
+ * Fire the 'bp_custom_profile_sidebar_boxes' action.
+ *
+ * No longer used in BuddyPress.
+ *
+ * @todo Deprecate.
+ */
 function bp_custom_profile_sidebar_boxes() {
 	do_action( 'bp_custom_profile_sidebar_boxes' );
 }
 
 /**
- * Creates and outputs a button.
+ * Create and output a button.
  *
- * @param array $args See bp_get_button() for the list of arguments.
  * @see bp_get_button()
+ *
+ * @param array $args See {@link BP_Button}.
  */
 function bp_button( $args = '' ) {
 	echo bp_get_button( $args );
 }
 	/**
-	 * Creates and returns a button.
+	 * Create and return a button.
 	 *
-	 * Args:
-	 * component: Which component this button is for
-	 * must_be_logged_in: Button only appears for logged in users
-	 * block_self: Button will not appear when viewing your own profile.
-	 * wrapper: div|span|p|li|
-	 * wrapper_id: The DOM ID of the button wrapper
-	 * wrapper_class: The DOM class of the button wrapper
-	 * link_href: The destination link of the button
-	 * link_title: Title of the button
-	 * link_id: The DOM ID of the button
-	 * link_class: The DOM class of the button
-	 * link_rel: The DOM rel of the button
-	 * link_text: The contents of the button
+	 * @see BP_Button for a description of arguments and return value.
 	 *
-	 * @param array $button
-	 * @return string
-	 * @see bp_add_friend_button()
-	 * @see bp_send_public_message_button()
-	 * @see bp_send_private_message_button()
+	 * @param array $args See {@link BP_Button}.
+	 * @return string HTML markup for the button.
 	 */
 	function bp_get_button( $args = '' ) {
 		$button = new BP_Button( $args );
 		return apply_filters( 'bp_get_button', $button->contents, $args, $button );
 	}
 
-
 /**
- * Truncates text.
+ * Truncate text.
  *
  * Cuts a string to the length of $length and replaces the last characters
  * with the ending if the text is longer than length.
@@ -364,11 +516,20 @@ function bp_button( $args = '' ) {
  * - `html` If true, HTML tags would be handled correctly
  * - `filter_shortcodes` If true, shortcodes will be stripped before truncating
  *
- * @package BuddyPress
- *
- * @param string  $text String to truncate.
- * @param integer $length Length of returned string, including ellipsis.
- * @param array $options An array of html attributes and options.
+ * @param string $text String to truncate.
+ * @param int $length Optional. Length of returned string, including ellipsis.
+ *        Default: 225.
+ * @param array $options {
+ *     An array of HTML attributes and options. Each item is optional.
+ *     @type string $ending The string used after truncation.
+ *           Default: ' [&hellip;]'.
+ *     @type bool $exact If true, $text will be trimmed to exactly $length.
+ *           If false, $text will not be cut mid-word. Default: false.
+ *     @type bool $html If true, don't include HTML tags when calculating
+ *           excerpt length. Default: true.
+ *     @type bool $filter_shortcodes If true, shortcodes will be stripped.
+ *           Default: true.
+ * }
  * @return string Trimmed string.
  */
 function bp_create_excerpt( $text, $length = 225, $options = array() ) {
@@ -489,30 +650,46 @@ add_filter( 'bp_create_excerpt', 'stripslashes_deep' );
 add_filter( 'bp_create_excerpt', 'force_balance_tags' );
 
 /**
- * Echoes the output of bp_get_total_member_count()
+ * Output the total member count for the site.
  */
 function bp_total_member_count() {
 	echo bp_get_total_member_count();
 }
 	/**
-	 * Returns the total member count in your BP instance
+	 * Return the total member count in your BP instance.
+	 *
+	 * Since BuddyPress 1.6, this function has used bp_core_get_active_member_count(),
+	 * which counts non-spam, non-deleted users who have last_activity.
+	 * This value will correctly match the total member count number used
+	 * for pagination on member directories.
 	 *
-	 * Since BuddyPress 1.6, this function has used bp_core_get_active_member_count(), which
-	 * counts non-spam, non-deleted users who have last_activity. This value will correctly
-	 * match the total member count number used for pagination on member directories.
+	 * Before BuddyPress 1.6, this function used bp_core_get_total_member_count(),
+	 * which did not take into account last_activity, and thus often
+	 * resulted in higher counts than shown by member directory pagination.
 	 *
-	 * Before BuddyPress 1.6, this function used bp_core_get_total_member_count(), which did
-	 * not take into account last_activity, and thus often resulted in higher counts than
-	 * shown by member directory pagination.
+	 * @return int Member count.
 	 */
 	function bp_get_total_member_count() {
 		return apply_filters( 'bp_get_total_member_count', bp_core_get_active_member_count() );
 	}
 	add_filter( 'bp_get_total_member_count', 'bp_core_number_format' );
 
+/**
+ * Output whether blog signup is allowed.
+ *
+ * @todo Deprecate. It doesn't make any sense to echo a boolean.
+ */
 function bp_blog_signup_allowed() {
 	echo bp_get_blog_signup_allowed();
 }
+	/**
+	 * Is blog signup allowed?
+	 *
+	 * Returns true if is_multisite() and blog creation is enabled at
+	 * Network Admin > Settings.
+	 *
+	 * @return bool True if blog signup is allowed, otherwise false.
+	 */
 	function bp_get_blog_signup_allowed() {
 		global $bp;
 
@@ -526,6 +703,12 @@ function bp_blog_signup_allowed() {
 		return false;
 	}
 
+/**
+ * Check whether an activation has just been completed.
+ *
+ * @return bool True if the activation_complete global flag has been set,
+ *         otherwise false.
+ */
 function bp_account_was_activated() {
 	global $bp;
 
@@ -534,20 +717,41 @@ function bp_account_was_activated() {
 	return $activation_complete;
 }
 
+/**
+ * Check whether registrations require activation on this installation.
+ *
+ * On a normal BuddyPress installation, all registrations require email
+ * activation. This filter exists so that customizations that omit activation
+ * can remove certain notification text from the registration screen.
+ *
+ * @return bool True by default.
+ */
 function bp_registration_needs_activation() {
 	return apply_filters( 'bp_registration_needs_activation', true );
 }
 
 /**
- * Retrieve a client friendly version of the root blog name, plus take care of
- * the typical formatting bits and bobs.
+ * Retrieve a client friendly version of the root blog name.
  *
  * The blogname option is escaped with esc_html on the way into the database in
  * sanitize_option, we want to reverse this for the plain text arena of emails.
  *
- * @link http://buddypress.trac.wordpress.org/ticket/4401
- * @since BuddyPress (1.7)
- * @return string
+ * @since BuddyPress (1.7.0)
+ *
+ * @see http://buddypress.trac.wordpress.org/ticket/4401
+ *
+ * @param array $args {
+ *     Array of optional parameters.
+ *     @type string $before String to appear before the site name in the
+ *           email subject. Default: '['.
+ *     @type string $after String to appear after the site name in the
+ *           email subject. Default: ']'.
+ *     @type string $default The default site name, to be used when none is
+ *           found in the database. Default: 'Community'.
+ *     @type string $text Text to append to the site name (ie, the main text of
+ *           the email subject).
+ * }
+ * @return string Sanitized email subject.
  */
 function bp_get_email_subject( $args = array() ) {
 
@@ -564,14 +768,17 @@ function bp_get_email_subject( $args = array() ) {
 }
 
 /**
- * Allow templates to pass parameters directly into the template loops via AJAX
+ * Allow templates to pass parameters directly into the template loops via AJAX.
+ *
+ * For the most part this will be filtered in a theme's functions.php for
+ * example in the default theme it is filtered via bp_dtheme_ajax_querystring().
  *
- * For the most part this will be filtered in a theme's functions.php for example
- * in the default theme it is filtered via bp_dtheme_ajax_querystring()
+ * By using this template tag in the templates it will stop them from showing
+ * errors if someone copies the templates from the default theme into another
+ * WordPress theme without coping the functions from functions.php.
  *
- * By using this template tag in the templates it will stop them from showing errors
- * if someone copies the templates from the default theme into another WordPress theme
- * without coping the functions from functions.php.
+ * @param string $object
+ * @return string The AJAX querystring.
  */
 function bp_ajax_querystring( $object = false ) {
 	global $bp;
@@ -584,18 +791,33 @@ function bp_ajax_querystring( $object = false ) {
 
 /** Template Classes and _is functions ****************************************/
 
+/**
+ * Return the name of the current component.
+ *
+ * @return string Component name.
+ */
 function bp_current_component() {
 	global $bp;
 	$current_component = !empty( $bp->current_component ) ? $bp->current_component : false;
 	return apply_filters( 'bp_current_component', $current_component );
 }
 
+/**
+ * Return the name of the current action.
+ *
+ * @return string Action name.
+ */
 function bp_current_action() {
 	global $bp;
 	$current_action = !empty( $bp->current_action ) ? $bp->current_action : '';
 	return apply_filters( 'bp_current_action', $current_action );
 }
 
+/**
+ * Return the name of the current item.
+ *
+ * @return unknown
+ */
 function bp_current_item() {
 	global $bp;
 	$current_item = !empty( $bp->current_item ) ? $bp->current_item : false;
@@ -603,11 +825,10 @@ function bp_current_item() {
 }
 
 /**
- * Return the value of $bp->action_variables
- *
- * @package BuddyPress
+ * Return the value of $bp->action_variables.
  *
- * @param mixed $action_variables The action variables array, or false if the array is empty
+ * @return array|bool $action_variables The action variables array, or false
+ *         if the array is empty.
  */
 function bp_action_variables() {
 	global $bp;
@@ -616,13 +837,13 @@ function bp_action_variables() {
 }
 
 /**
- * Return the value of a given action variable
+ * Return the value of a given action variable.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param int $position The key of the action_variables array that you want
- * @return string $action_variable The value of that position in the array
+ * @param int $position The key of the action_variables array that you want.
+ * @return string|bool $action_variable The value of that position in the
+ *         array, or false if not found.
  */
 function bp_action_variable( $position = 0 ) {
 	$action_variables = bp_action_variables();
@@ -631,9 +852,17 @@ function bp_action_variable( $position = 0 ) {
 	return apply_filters( 'bp_action_variable', $action_variable, $position );
 }
 
+/**
+ * Output the "root domain", the URL of the BP root blog.
+ */
 function bp_root_domain() {
 	echo bp_get_root_domain();
 }
+	/**
+	 * Return the "root domain", the URL of the BP root blog.
+	 *
+	 * @return string URL of the BP root blog.
+	 */
 	function bp_get_root_domain() {
 		global $bp;
 
@@ -648,35 +877,46 @@ function bp_root_domain() {
 	}
 
 /**
- * Echoes the output of bp_get_root_slug()
+ * Output the root slug for a given component.
+ *
+ * @since BuddyPress (1.5.0)
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @param string $component The component name.
  */
 function bp_root_slug( $component = '' ) {
 	echo bp_get_root_slug( $component );
 }
 	/**
-	 * Gets the root slug for a component slug
+	 * Get the root slug for given component.
 	 *
-	 * In order to maintain backward compatibility, the following procedure is used:
+	 * The "root slug" is the string used when concatenating component
+	 * directory URLs. For example, on an installation where the Groups
+	 * component's directory is located at http://example.com/groups/, the
+	 * root slug for the Groups component is 'groups'. This string
+	 * generally corresponds to page_name of the component's directory
+	 * page.
+	 *
+	 * In order to maintain backward compatibility, the following procedure
+	 * is used:
 	 * 1) Use the short slug to get the canonical component name from the
 	 *    active component array
-	 * 2) Use the component name to get the root slug out of the appropriate part of the $bp
-	 *    global
-	 * 3) If nothing turns up, it probably means that $component is itself a root slug
+	 * 2) Use the component name to get the root slug out of the
+	 *    appropriate part of the $bp global
+	 * 3) If nothing turns up, it probably means that $component is itself
+	 *    a root slug
+	 *
+	 * Example: If your groups directory is at /community/companies, this
+	 * function first uses the short slug 'companies' (ie the current
+	 * component) to look up the canonical name 'groups' in
+	 * $bp->active_components. Then it uses 'groups' to get the root slug,
+	 * from $bp->groups->root_slug.
 	 *
-	 * Example: If your groups directory is at /community/companies, this function first uses
-	 * the short slug 'companies' (ie the current component) to look up the canonical name
-	 * 'groups' in $bp->active_components. Then it uses 'groups' to get the root slug, from
-	 * $bp->groups->root_slug.
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @package BuddyPress Core
-	 * @since BuddyPress (1.5)
+	 * @global BuddyPress $bp The one true BuddyPress instance.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
-	 * @param string $component Optional. Defaults to the current component
-	 * @return string $root_slug The root slug
+	 * @param string $component Optional. Defaults to the current component.
+	 * @return string $root_slug The root slug.
 	 */
 	function bp_get_root_slug( $component = '' ) {
 		global $bp;
@@ -707,12 +947,14 @@ function bp_root_slug( $component = '' ) {
 	}
 
 /**
- * Return the component name based on the current root slug
+ * Return the component name based on a root slug.
+ *
+ * @since BuddyPress (1.5.0)
+ *
+ * @global BuddyPress $bp The one true BuddyPress instance.
  *
- * @since BuddyPress (1.5)
- * @global BuddyPress $bp The one true BuddyPress instance
- * @param string $root_slug Needle to our active component haystack
- * @return mixed False if none found, component name if found
+ * @param string $root_slug Needle to our active component haystack.
+ * @return mixed False if none found, component name if found.
  */
 function bp_get_name_from_root_slug( $root_slug = '' ) {
 	global $bp;
@@ -742,10 +984,9 @@ function bp_user_has_access() {
 }
 
 /**
- * Output the search slug
+ * Output the search slug.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_search_slug()
  */
@@ -753,20 +994,22 @@ function bp_search_slug() {
 	echo bp_get_search_slug();
 }
 	/**
-	 * Return the search slug
+	 * Return the search slug.
+	 *
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @package BuddyPress
-	 * @since BuddyPress (1.5)
+	 * @return string The search slug. Default: 'search'.
 	 */
 	function bp_get_search_slug() {
 		return apply_filters( 'bp_get_search_slug', BP_SEARCH_SLUG );
 	}
 
 /**
- * Get the id of the currently displayed user
+ * Get the ID of the currently displayed user.
+ *
+ * @uses apply_filters() Filter 'bp_displayed_user_id' to change this value.
  *
- * @uses apply_filters() Filter 'bp_displayed_user_id' to change this value
- * @return int
+ * @return int ID of the currently displayed user.
  */
 function bp_displayed_user_id() {
 	$bp = buddypress();
@@ -776,10 +1019,11 @@ function bp_displayed_user_id() {
 }
 
 /**
- * Get the id of the currently logged-in user
+ * Get the ID of the currently logged-in user.
  *
- * @uses apply_filters() Filter 'bp_loggedin_user_id' to change this value
- * @return int
+ * @uses apply_filters() Filter 'bp_loggedin_user_id' to change this value.
+ *
+ * @return int ID of the logged-in user.
  */
 function bp_loggedin_user_id() {
 	$bp = buddypress();
@@ -791,7 +1035,7 @@ function bp_loggedin_user_id() {
 /** is_() functions to determine the current page *****************************/
 
 /**
- * Checks to see whether the current page belongs to the specified component
+ * Check to see whether the current page belongs to the specified component.
  *
  * This function is designed to be generous, accepting several different kinds
  * of value for the $component parameter. It checks $component_name against:
@@ -799,20 +1043,26 @@ function bp_loggedin_user_id() {
  * - the component's regular slug
  * - the component's id, or 'canonical' name
  *
- * @package BuddyPress Core
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @param string $component Name of the component being checked.
  * @return bool Returns true if the component matches, or else false.
  */
 function bp_is_current_component( $component ) {
-	global $bp;
+	global $bp, $wp_query;
 
 	$is_current_component = false;
 
+	// Always return false if a null value is passed to the function
+	if ( empty( $component ) ) {
+		return false;
+	}
+
 	// Backward compatibility: 'xprofile' should be read as 'profile'
 	if ( 'xprofile' == $component )
 		$component = 'profile';
 
-	if ( !empty( $bp->current_component ) ) {
+	if ( ! empty( $bp->current_component ) ) {
 
 		// First, check to see whether $component_name and the current
 		// component are a simple match
@@ -854,7 +1104,7 @@ function bp_is_current_component( $component ) {
 		}
 
 	// Page template fallback check if $bp->current_component is empty
-	} elseif ( !is_admin() && is_page() ) {
+	} elseif ( !is_admin() && is_a( $wp_query, 'WP_Query' ) && is_page() ) {
 		global $wp_query;
 		$page          = $wp_query->get_queried_object();
 		$custom_fields = get_post_custom_values( '_wp_page_template', $page->ID );
@@ -872,19 +1122,19 @@ function bp_is_current_component( $component ) {
 /**
  * Check to see whether the current page matches a given action.
  *
- * Along with bp_is_current_component() and bp_is_action_variable(), this function is mostly used
- * to help determine when to use a given screen function.
+ * Along with bp_is_current_component() and bp_is_action_variable(), this
+ * function is mostly used to help determine when to use a given screen
+ * function.
  *
- * In BP parlance, the current_action is the URL chunk that comes directly after the
- * current item slug. E.g., in
+ * In BP parlance, the current_action is the URL chunk that comes directly
+ * after the current item slug. E.g., in
  *   http://example.com/groups/my-group/members
  * the current_action is 'members'.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param string $action The action being tested against
- * @return bool True if the current action matches $action
+ * @param string $action The action being tested against.
+ * @return bool True if the current action matches $action.
  */
 function bp_is_current_action( $action = '' ) {
 	if ( $action == bp_current_action() )
@@ -896,22 +1146,22 @@ function bp_is_current_action( $action = '' ) {
 /**
  * Check to see whether the current page matches a given action_variable.
  *
- * Along with bp_is_current_component() and bp_is_current_action(), this function is mostly used
- * to help determine when to use a given screen function.
+ * Along with bp_is_current_component() and bp_is_current_action(), this
+ * function is mostly used to help determine when to use a given screen
+ * function.
  *
- * In BP parlance, action_variables are an array made up of the URL chunks appearing after the
- * current_action in a URL. For example,
+ * In BP parlance, action_variables are an array made up of the URL chunks
+ * appearing after the current_action in a URL. For example,
  *   http://example.com/groups/my-group/admin/group-settings
  * $action_variables[0] is 'group-settings'.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param string $action_variable The action_variable being tested against
- * @param int $position The array key you're testing against. If you don't provide a $position,
- *   the function will return true if the $action_variable is found *anywhere* in the action
- *   variables array.
- * @return bool
+ * @param string $action_variable The action_variable being tested against.
+ * @param int $position Optional. The array key you're testing against. If you
+ *        don't provide a $position, the function will return true if the
+ *        $action_variable is found *anywhere* in the action variables array.
+ * @return bool True if $action_variable matches at the $position provided.
  */
 function bp_is_action_variable( $action_variable = '', $position = false ) {
 	$is_action_variable = false;
@@ -933,6 +1183,12 @@ function bp_is_action_variable( $action_variable = '', $position = false ) {
 	return apply_filters( 'bp_is_action_variable', $is_action_variable, $action_variable, $position );
 }
 
+/**
+ * Check against the current_item.
+ *
+ * @param string $item The item being checked.
+ * @return bool True if $item is the current item.
+ */
 function bp_is_current_item( $item = '' ) {
 	if ( !empty( $item ) && $item == bp_current_item() )
 		return true;
@@ -940,6 +1196,11 @@ function bp_is_current_item( $item = '' ) {
 	return false;
 }
 
+/**
+ * Are we looking at a single item? (group, user, etc)
+ *
+ * @return bool True if looking at a single item, otherwise false.
+ */
 function bp_is_single_item() {
 	global $bp;
 
@@ -949,6 +1210,12 @@ function bp_is_single_item() {
 	return false;
 }
 
+/**
+ * Is the logged-in user an admin for the current item?
+ *
+ * @return bool True if the current user is an admin for the current item,
+ *         otherwise false.
+ */
 function bp_is_item_admin() {
 	global $bp;
 
@@ -958,6 +1225,12 @@ function bp_is_item_admin() {
 	return false;
 }
 
+/**
+ * Is the logged-in user a mod for the current item?
+ *
+ * @return bool True if the current user is a mod for the current item,
+ *         otherwise false.
+ */
 function bp_is_item_mod() {
 	global $bp;
 
@@ -967,6 +1240,12 @@ function bp_is_item_mod() {
 	return false;
 }
 
+/**
+ * Is this a component directory page?
+ *
+ * @return bool True if the current page is a component directory, otherwise
+ *         false.
+ */
 function bp_is_directory() {
 	global $bp;
 
@@ -977,13 +1256,11 @@ function bp_is_directory() {
 }
 
 /**
- * Checks to see if a component's URL should be in the root, not under a
- * member page:
+ * Check to see if a component's URL should be in the root, not under a member page.
  *
- *   Yes: http://domain.com/groups/the-group
- *   No:  http://domain.com/members/andy/groups/the-group
+ *   Yes ('groups' is root): http://domain.com/groups/the-group
+ *   No ('groups' is not-root):  http://domain.com/members/andy/groups/the-group
  *
- * @package BuddyPress Core
  * @return bool True if root component, else false.
  */
 function bp_is_root_component( $component_name ) {
@@ -1001,14 +1278,19 @@ function bp_is_root_component( $component_name ) {
 }
 
 /**
- * Checks if the site's front page is set to the specified BuddyPress component
- * page in wp-admin's Settings > Reading screen.
+ * Check if the specified BuddyPress component directory is set to be the front page.
+ *
+ * Corresponds to the setting in wp-admin's Settings > Reading screen.
+ *
+ * @since BuddyPress (1.5.0)
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @global $current_blog WordPress global for the current blog
- * @param string $component Optional; Name of the component to check for.
- * @return bool True If the specified component is set to be the site's front page.
- * @since BuddyPress (1.5)
+ * @global BuddyPress $bp The one true BuddyPress instance.
+ * @global $current_blog WordPress global for the current blog.
+ *
+ * @param string $component Optional. Name of the component to check for.
+ *        Default: current component.
+ * @return bool True if the specified component is set to be the site's front
+ *         page, otherwise false.
  */
 function bp_is_component_front_page( $component = '' ) {
 	global $bp, $current_blog;
@@ -1027,11 +1309,10 @@ function bp_is_component_front_page( $component = '' ) {
 /**
  * Is this a blog page, ie a non-BP page?
  *
- * You can tell if a page is displaying BP content by whether the current_component has been defined
- *
- * @package BuddyPress
+ * You can tell if a page is displaying BP content by whether the
+ * current_component has been defined.
  *
- * @return bool True if it's a non-BP page, false otherwise
+ * @return bool True if it's a non-BP page, false otherwise.
  */
 function bp_is_blog_page() {
 
@@ -1050,16 +1331,15 @@ function bp_is_blog_page() {
  * Is this a BuddyPress component?
  *
  * You can tell if a page is displaying BP content by whether the
- * current_component has been defined
+ * current_component has been defined.
  *
  * Generally, we can just check to see that there's no current component.
  * The one exception is single user home tabs, where $bp->current_component
  * is unset. Thus the addition of the bp_is_user() check.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @package BuddyPress
- * @return bool True if it's a BuddyPress page, false otherwise
+ * @return bool True if it's a BuddyPress page, false otherwise.
  */
 function is_buddypress() {
 	$retval = (bool) ( bp_current_component() || bp_is_user() );
@@ -1069,6 +1349,12 @@ function is_buddypress() {
 
 /** Components ****************************************************************/
 
+/**
+ * Check whether a given component has been activated by the admin.
+ *
+ * @param string $component The component name.
+ * @return bool True if the component is active, otherwise false.
+ */
 function bp_is_active( $component ) {
 	global $bp;
 
@@ -1078,6 +1364,11 @@ function bp_is_active( $component ) {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Members component.
+ *
+ * @return bool True if the current page is part of the Members component.
+ */
 function bp_is_members_component() {
 	if ( bp_is_current_component( 'members' ) )
 		return true;
@@ -1085,6 +1376,11 @@ function bp_is_members_component() {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Profile component.
+ *
+ * @return bool True if the current page is part of the Profile component.
+ */
 function bp_is_profile_component() {
 	if ( bp_is_current_component( 'xprofile' ) )
 		return true;
@@ -1092,6 +1388,11 @@ function bp_is_profile_component() {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Activity component.
+ *
+ * @return bool True if the current page is part of the Activity component.
+ */
 function bp_is_activity_component() {
 	if ( bp_is_current_component( 'activity' ) )
 		return true;
@@ -1099,6 +1400,11 @@ function bp_is_activity_component() {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Blogs component.
+ *
+ * @return bool True if the current page is part of the Blogs component.
+ */
 function bp_is_blogs_component() {
 	if ( is_multisite() && bp_is_current_component( 'blogs' ) )
 		return true;
@@ -1106,6 +1412,11 @@ function bp_is_blogs_component() {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Messages component.
+ *
+ * @return bool True if the current page is part of the Messages component.
+ */
 function bp_is_messages_component() {
 	if ( bp_is_current_component( 'messages' ) )
 		return true;
@@ -1113,6 +1424,11 @@ function bp_is_messages_component() {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Friends component.
+ *
+ * @return bool True if the current page is part of the Friends component.
+ */
 function bp_is_friends_component() {
 	if ( bp_is_current_component( 'friends' ) )
 		return true;
@@ -1120,6 +1436,11 @@ function bp_is_friends_component() {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Groups component.
+ *
+ * @return bool True if the current page is part of the Groups component.
+ */
 function bp_is_groups_component() {
 	if ( bp_is_current_component( 'groups' ) )
 		return true;
@@ -1127,6 +1448,11 @@ function bp_is_groups_component() {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Forums component.
+ *
+ * @return bool True if the current page is part of the Forums component.
+ */
 function bp_is_forums_component() {
 	if ( bp_is_current_component( 'forums' ) )
 		return true;
@@ -1134,6 +1460,26 @@ function bp_is_forums_component() {
 	return false;
 }
 
+/**
+ * Check whether the current page is part of the Notifications component.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return bool True if the current page is part of the Notifications component.
+ */
+function bp_is_notifications_component() {
+	if ( bp_is_current_component( 'notifications' ) ) {
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * Check whether the current page is part of the Settings component.
+ *
+ * @return bool True if the current page is part of the Settings component.
+ */
 function bp_is_settings_component() {
 	if ( bp_is_current_component( 'settings' ) )
 		return true;
@@ -1142,7 +1488,7 @@ function bp_is_settings_component() {
 }
 
 /**
- * Is the current component an active core component.
+ * Is the current component an active core component?
  *
  * Use this function when you need to check if the current component is an
  * active core component of BuddyPress. If the current component is inactive, it
@@ -1150,8 +1496,8 @@ function bp_is_settings_component() {
  * it will return false. If the current component is active, and is part of
  * BuddyPress core, it will return true.
  *
- * @since BuddyPress (1.7)
- * @return boolean
+ * @return bool True if the current component is active and is one of BP's
+ *         packaged components.
  */
 function bp_is_current_component_core() {
 	$retval            = false;
@@ -1169,6 +1515,25 @@ function bp_is_current_component_core() {
 
 /** Activity ******************************************************************/
 
+/**
+ * Is the current page the activity directory ?
+ *
+ * @since BuddyPress (2.0.0)
+ * 
+ * @return True if the current page is the activity directory.
+ */
+function bp_is_activity_directory() {
+	if ( ! bp_displayed_user_id() && bp_is_activity_component() && ! bp_current_action() )
+		return true;
+
+	return false;
+}
+
+/**
+ * Is the current page a single activity item permalink?
+ *
+ * @return True if the current page is a single activity item permalink.
+ */
 function bp_is_single_activity() {
 	if ( bp_is_activity_component() && is_numeric( bp_current_action() ) )
 		return true;
@@ -1178,6 +1543,28 @@ function bp_is_single_activity() {
 
 /** User **********************************************************************/
 
+/**
+ * Is the current page the members directory ?
+ *
+ * @since BuddyPress (2.0.0)
+ * 
+ * @return True if the current page is the members directory.
+ */
+function bp_is_members_directory() {
+	if ( ! bp_is_user() && bp_is_members_component() )
+		return true;
+
+	return false;
+}
+
+/**
+ * Is the current page part of the profile of the logged-in user?
+ *
+ * Will return true for any subpage of the logged-in user's profile, eg
+ * http://example.com/members/joe/friends/.
+ *
+ * @return True if the current page is part of the profile of the logged-in user.
+ */
 function bp_is_my_profile() {
 	if ( is_user_logged_in() && bp_loggedin_user_id() == bp_displayed_user_id() )
 		$my_profile = true;
@@ -1187,6 +1574,13 @@ function bp_is_my_profile() {
 	return apply_filters( 'bp_is_my_profile', $my_profile );
 }
 
+/**
+ * Is the current page a user page?
+ *
+ * Will return true anytime there is a displayed user.
+ *
+ * @return True if the current page is a user page.
+ */
 function bp_is_user() {
 	if ( bp_displayed_user_id() )
 		return true;
@@ -1194,6 +1588,13 @@ function bp_is_user() {
 	return false;
 }
 
+/**
+ * Is the current page a user's activity stream page?
+ *
+ * Eg http://example.com/members/joe/activity/ (or any subpages thereof).
+ *
+ * @return True if the current page is a user's activity stream page.
+ */
 function bp_is_user_activity() {
 	if ( bp_is_user() && bp_is_activity_component() )
 		return true;
@@ -1201,6 +1602,13 @@ function bp_is_user_activity() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Friends activity stream?
+ *
+ * Eg http://example.com/members/joe/friends/
+ *
+ * @return True if the current page is a user's Friends activity stream.
+ */
 function bp_is_user_friends_activity() {
 
 	if ( !bp_is_active( 'friends' ) )
@@ -1217,6 +1625,13 @@ function bp_is_user_friends_activity() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Groups activity stream?
+ *
+ * Eg http://example.com/members/joe/groups/
+ *
+ * @return True if the current page is a user's Groups activity stream.
+ */
 function bp_is_user_groups_activity() {
 
 	if ( !bp_is_active( 'groups' ) )
@@ -1233,6 +1648,13 @@ function bp_is_user_groups_activity() {
 	return false;
 }
 
+/**
+ * Is the current page part of a user's extended profile?
+ *
+ * Eg http://example.com/members/joe/profile/ (or a subpage thereof).
+ *
+ * @return True if the current page is part of a user's extended profile.
+ */
 function bp_is_user_profile() {
 	if ( bp_is_profile_component() || bp_is_current_component( 'profile' ) )
 		return true;
@@ -1240,6 +1662,13 @@ function bp_is_user_profile() {
 	return false;
 }
 
+/**
+ * Is the current page part of a user's profile editing section?
+ *
+ * Eg http://example.com/members/joe/profile/edit/ (or a subpage thereof).
+ *
+ * @return True if the current page is a user's profile edit page.
+ */
 function bp_is_user_profile_edit() {
 	if ( bp_is_profile_component() && bp_is_current_action( 'edit' ) )
 		return true;
@@ -1257,9 +1686,9 @@ function bp_is_user_change_avatar() {
 /**
  * Is this a user's forums page?
  *
- * @package BuddyPress
+ * Eg http://example.com/members/joe/forums/ (or a subpage thereof).
  *
- * @return bool
+ * @return bool True if the current page is a user's forums page.
  */
 function bp_is_user_forums() {
 
@@ -1275,10 +1704,11 @@ function bp_is_user_forums() {
 /**
  * Is this a user's "Topics Started" page?
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * Eg http://example.com/members/joe/forums/topics/.
  *
- * @return bool
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool True if the current page is a user's Topics Started page.
  */
 function bp_is_user_forums_started() {
 	if ( bp_is_user_forums() && bp_is_current_action( 'topics' ) )
@@ -1290,10 +1720,11 @@ function bp_is_user_forums_started() {
 /**
  * Is this a user's "Replied To" page?
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * Eg http://example.com/members/joe/forums/replies/.
  *
- * @return bool
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool True if the current page is a user's Replied To forums page.
  */
 function bp_is_user_forums_replied_to() {
 	if ( bp_is_user_forums() && bp_is_current_action( 'replies' ) )
@@ -1302,6 +1733,13 @@ function bp_is_user_forums_replied_to() {
 	return false;
 }
 
+/**
+ * Is the current page part of a user's Groups page?
+ *
+ * Eg http://example.com/members/joe/groups/ (or a subpage thereof).
+ *
+ * @return bool True if the current page is a user's Groups page.
+ */
 function bp_is_user_groups() {
 	if ( bp_is_user() && bp_is_groups_component() )
 		return true;
@@ -1309,6 +1747,13 @@ function bp_is_user_groups() {
 	return false;
 }
 
+/**
+ * Is the current page part of a user's Blogs page?
+ *
+ * Eg http://example.com/members/joe/blogs/ (or a subpage thereof).
+ *
+ * @return bool True if the current page is a user's Blogs page.
+ */
 function bp_is_user_blogs() {
 	if ( bp_is_user() && bp_is_blogs_component() )
 		return true;
@@ -1316,6 +1761,13 @@ function bp_is_user_blogs() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Recent Blog Posts page?
+ *
+ * Eg http://example.com/members/joe/blogs/recent-posts/.
+ *
+ * @return bool True if the current page is a user's Recent Blog Posts page.
+ */
 function bp_is_user_recent_posts() {
 	if ( bp_is_user_blogs() && bp_is_current_action( 'recent-posts' ) )
 		return true;
@@ -1323,6 +1775,13 @@ function bp_is_user_recent_posts() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Recent Blog Comments page?
+ *
+ * Eg http://example.com/members/joe/blogs/recent-comments/.
+ *
+ * @return bool True if the current page is a user's Recent Blog Comments page.
+ */
 function bp_is_user_recent_commments() {
 	if ( bp_is_user_blogs() && bp_is_current_action( 'recent-comments' ) )
 		return true;
@@ -1330,6 +1789,13 @@ function bp_is_user_recent_commments() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Friends page?
+ *
+ * Eg http://example.com/members/joe/blogs/friends/ (or a subpage thereof).
+ *
+ * @return bool True if the current page is a user's Friends page.
+ */
 function bp_is_user_friends() {
 	if ( bp_is_user() && bp_is_friends_component() )
 		return true;
@@ -1337,6 +1803,13 @@ function bp_is_user_friends() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Friend Requests page?
+ *
+ * Eg http://example.com/members/joe/friends/requests/.
+ *
+ * @return bool True if the current page is a user's Friends Requests page.
+ */
 function bp_is_user_friend_requests() {
 	if ( bp_is_user_friends() && bp_is_current_action( 'requests' ) )
 		return true;
@@ -1344,12 +1817,29 @@ function bp_is_user_friend_requests() {
 	return false;
 }
 
+/**
+ * Is this a user's notifications page?
+ *
+ * Eg http://example.com/members/joe/notifications/ (or a subpage thereof).
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return bool True if the current page is a user's Notifications page.
+ */
+function bp_is_user_notifications() {
+	if ( bp_is_user() && bp_is_notifications_component() ) {
+		return true;
+	}
+
+	return false;
+}
+
 /**
  * Is this a user's settings page?
  *
- * @package BuddyPress
+ * Eg http://example.com/members/joe/settings/ (or a subpage thereof).
  *
- * @return bool
+ * @return bool True if the current page is a user's Settings page.
  */
 function bp_is_user_settings() {
 	if ( bp_is_user() && bp_is_settings_component() )
@@ -1361,10 +1851,11 @@ function bp_is_user_settings() {
 /**
  * Is this a user's General Settings page?
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * Eg http://example.com/members/joe/settings/general/.
  *
- * @return bool
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool True if the current page is a user's General Settings page.
  */
 function bp_is_user_settings_general() {
 	if ( bp_is_user_settings() && bp_is_current_action( 'general' ) )
@@ -1376,10 +1867,11 @@ function bp_is_user_settings_general() {
 /**
  * Is this a user's Notification Settings page?
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * Eg http://example.com/members/joe/settings/notifications/.
  *
- * @return bool
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool True if the current page is a user's Notification Settings page.
  */
 function bp_is_user_settings_notifications() {
 	if ( bp_is_user_settings() && bp_is_current_action( 'notifications' ) )
@@ -1391,10 +1883,11 @@ function bp_is_user_settings_notifications() {
 /**
  * Is this a user's Account Deletion page?
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * Eg http://example.com/members/joe/settings/delete-account/.
  *
- * @return bool
+ * @since BuddyPress (1.5.0)
+ *
+ * @return bool True if the current page is a user's Delete Account page.
  */
 function bp_is_user_settings_account_delete() {
 	if ( bp_is_user_settings() && bp_is_current_action( 'delete-account' ) )
@@ -1403,9 +1896,45 @@ function bp_is_user_settings_account_delete() {
 	return false;
 }
 
+/**
+ * Is this a user's profile settings?
+ *
+ * Eg http://example.com/members/joe/settings/profile/.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return bool True if the current page is a user's Profile Settings page.
+ */
+function bp_is_user_settings_profile() {
+	if ( bp_is_user_settings() && bp_is_current_action( 'profile' ) )
+		return true;
+
+	return false;
+}
+
+/** Groups ********************************************************************/
 
-/** Groups ******************************************************************/
+/**
+ * Is the current page the groups directory ?
+ *
+ * @since BuddyPress (2.0.0)
+ * 
+ * @return True if the current page is the groups directory.
+ */
+function bp_is_groups_directory() {
+	if ( bp_is_groups_component() && ! bp_current_action() && ! bp_current_item() )
+		return true;
 
+	return false;
+}
+
+/**
+ * Does the current page belong to a single group?
+ *
+ * Will return true for any subpage of a single group.
+ *
+ * @return bool True if the current page is part of a single group.
+ */
 function bp_is_group() {
 	global $bp;
 
@@ -1415,6 +1944,14 @@ function bp_is_group() {
 	return false;
 }
 
+/**
+ * Is the current page a single group's home page?
+ *
+ * URL will vary depending on which group tab is set to be the "home". By
+ * default, it's the group's recent activity.
+ *
+ * @return bool True if the current page is a single group's home page.
+ */
 function bp_is_group_home() {
 	if ( bp_is_single_item() && bp_is_groups_component() && ( !bp_current_action() || bp_is_current_action( 'home' ) ) )
 		return true;
@@ -1422,6 +1959,11 @@ function bp_is_group_home() {
 	return false;
 }
 
+/**
+ * Is the current page part of the group creation process?
+ *
+ * @return bool True if the current page is part of the group creation process.
+ */
 function bp_is_group_create() {
 	if ( bp_is_groups_component() && bp_is_current_action( 'create' ) )
 		return true;
@@ -1429,6 +1971,13 @@ function bp_is_group_create() {
 	return false;
 }
 
+/**
+ * Is the current page part of a single group's admin screens?
+ *
+ * Eg http://example.com/groups/mygroup/admin/settings/.
+ *
+ * @return bool True if the current page is part of a single group's admin.
+ */
 function bp_is_group_admin_page() {
 	if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'admin' ) )
 		return true;
@@ -1436,6 +1985,13 @@ function bp_is_group_admin_page() {
 	return false;
 }
 
+/**
+ * Is the current page a group's forum page?
+ *
+ * Only applies to legacy bbPress forums.
+ *
+ * @return bool True if the current page is a group forum page.
+ */
 function bp_is_group_forum() {
 	$retval = false;
 
@@ -1453,6 +2009,11 @@ function bp_is_group_forum() {
 	return $retval;
 }
 
+/**
+ * Is the current page a group's activity page?
+ *
+ * @return True if the current page is a group's activity page.
+ */
 function bp_is_group_activity() {
 	if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'activity' ) )
 		return true;
@@ -1460,6 +2021,13 @@ function bp_is_group_activity() {
 	return false;
 }
 
+/**
+ * Is the current page a group forum topic?
+ *
+ * Only applies to legacy bbPress (1.x) forums.
+ *
+ * @return bool True if the current page is part of a group forum topic.
+ */
 function bp_is_group_forum_topic() {
 	if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'forum' ) && bp_is_action_variable( 'topic', 0 ) )
 		return true;
@@ -1467,6 +2035,13 @@ function bp_is_group_forum_topic() {
 	return false;
 }
 
+/**
+ * Is the current page a group forum topic edit page?
+ *
+ * Only applies to legacy bbPress (1.x) forums.
+ *
+ * @return bool True if the current page is part of a group forum topic edit page.
+ */
 function bp_is_group_forum_topic_edit() {
 	if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'forum' ) && bp_is_action_variable( 'topic', 0 ) && bp_is_action_variable( 'edit', 2 ) )
 		return true;
@@ -1474,6 +2049,13 @@ function bp_is_group_forum_topic_edit() {
 	return false;
 }
 
+/**
+ * Is the current page a group's Members page?
+ *
+ * Eg http://example.com/groups/mygroup/members/.
+ *
+ * @return bool True if the current page is part of a group's Members page.
+ */
 function bp_is_group_members() {
 	if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'members' ) )
 		return true;
@@ -1481,6 +2063,13 @@ function bp_is_group_members() {
 	return false;
 }
 
+/**
+ * Is the current page a group's Invites page?
+ *
+ * Eg http://example.com/groups/mygroup/send-invites/.
+ *
+ * @return bool True if the current page is a group's Send Invites page.
+ */
 function bp_is_group_invites() {
 	if ( bp_is_groups_component() && bp_is_current_action( 'send-invites' ) )
 		return true;
@@ -1488,6 +2077,13 @@ function bp_is_group_invites() {
 	return false;
 }
 
+/**
+ * Is the current page a group's Request Membership page?
+ *
+ * Eg http://example.com/groups/mygroup/request-membership/.
+ *
+ * @return bool True if the current page is a group's Request Membership page.
+ */
 function bp_is_group_membership_request() {
 	if ( bp_is_groups_component() && bp_is_current_action( 'request-membership' ) )
 		return true;
@@ -1495,6 +2091,11 @@ function bp_is_group_membership_request() {
 	return false;
 }
 
+/**
+ * Is the current page a leave group attempt?
+ *
+ * @return bool True if the current page is a Leave Group attempt.
+ */
 function bp_is_group_leave() {
 
 	if ( bp_is_groups_component() && bp_is_single_item() && bp_is_current_action( 'leave-group' ) )
@@ -1503,6 +2104,15 @@ function bp_is_group_leave() {
 	return false;
 }
 
+/**
+ * Is the current page part of a single group?
+ *
+ * Not currently used by BuddyPress.
+ *
+ * @todo How is this functionally different from bp_is_group()?
+ *
+ * @return bool True if the current page is part of a single group.
+ */
 function bp_is_group_single() {
 	if ( bp_is_groups_component() && bp_is_single_item() )
 		return true;
@@ -1510,6 +2120,13 @@ function bp_is_group_single() {
 	return false;
 }
 
+/**
+ * Is the current page the Create a Blog page?
+ *
+ * Eg http://example.com/sites/create/.
+ *
+ * @return bool True if the current page is the Create a Blog page.
+ */
 function bp_is_create_blog() {
 	if ( bp_is_blogs_component() && bp_is_current_action( 'create' ) )
 		return true;
@@ -1517,8 +2134,29 @@ function bp_is_create_blog() {
 	return false;
 }
 
+/**
+ * Is the current page the blogs directory ?
+ *
+ * @since BuddyPress (2.0.0)
+ * 
+ * @return True if the current page is the blogs directory.
+ */
+function bp_is_blogs_directory() {
+	if ( is_multisite() && bp_is_blogs_component() && ! bp_current_action() )
+		return true;
+
+	return false;
+}
+
 /** Messages ******************************************************************/
 
+/**
+ * Is the current page part of a user's Messages pages?
+ *
+ * Eg http://example.com/members/joe/messages/ (or a subpage thereof).
+ *
+ * @return bool True if the current page is part of a user's Messages pages.
+ */
 function bp_is_user_messages() {
 	if ( bp_is_user() && bp_is_messages_component() )
 		return true;
@@ -1526,6 +2164,13 @@ function bp_is_user_messages() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Messages Inbox?
+ *
+ * Eg http://example.com/members/joe/messages/inbox/.
+ *
+ * @return bool True if the current page is a user's Messages Inbox.
+ */
 function bp_is_messages_inbox() {
 	if ( bp_is_user_messages() && ( !bp_current_action() || bp_is_current_action( 'inbox' ) ) )
 		return true;
@@ -1533,6 +2178,13 @@ function bp_is_messages_inbox() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Messages Sentbox?
+ *
+ * Eg http://example.com/members/joe/messages/sentbox/.
+ *
+ * @return bool True if the current page is a user's Messages Sentbox.
+ */
 function bp_is_messages_sentbox() {
 	if ( bp_is_user_messages() && bp_is_current_action( 'sentbox' ) )
 		return true;
@@ -1540,6 +2192,13 @@ function bp_is_messages_sentbox() {
 	return false;
 }
 
+/**
+ * Is the current page a user's Messages Compose screen??
+ *
+ * Eg http://example.com/members/joe/messages/compose/.
+ *
+ * @return bool True if the current page is a user's Messages Compose screen.
+ */
 function bp_is_messages_compose_screen() {
 	if ( bp_is_user_messages() && bp_is_current_action( 'compose' ) )
 		return true;
@@ -1547,6 +2206,13 @@ function bp_is_messages_compose_screen() {
 	return false;
 }
 
+/**
+ * Is the current page the Notices screen?
+ *
+ * Eg http://example.com/members/joe/messages/notices/.
+ *
+ * @return bool True if the current page is the Notices screen.
+ */
 function bp_is_notices() {
 	if ( bp_is_user_messages() && bp_is_current_action( 'notices' ) )
 		return true;
@@ -1554,6 +2220,11 @@ function bp_is_notices() {
 	return false;
 }
 
+/**
+ * Is the current page a single Messages conversation thread?
+ *
+ * @return bool True if the current page a single Messages conversation thread?
+ */
 function bp_is_messages_conversation() {
 	if ( bp_is_user_messages() && ( bp_is_current_action( 'view' ) ) )
 		return true;
@@ -1561,6 +2232,11 @@ function bp_is_messages_conversation() {
 	return false;
 }
 
+/**
+ * Not currently used by BuddyPress.
+ *
+ * @return bool
+ */
 function bp_is_single( $component, $callback ) {
 	if ( bp_is_current_component( $component ) && ( true === call_user_func( $callback ) ) )
 		return true;
@@ -1570,6 +2246,13 @@ function bp_is_single( $component, $callback ) {
 
 /** Registration **************************************************************/
 
+/**
+ * Is the current page the Activate page?
+ *
+ * Eg http://example.com/activate/.
+ *
+ * @return bool True if the current page is the Activate page.
+ */
 function bp_is_activation_page() {
 	if ( bp_is_current_component( 'activate' ) )
 		return true;
@@ -1577,6 +2260,13 @@ function bp_is_activation_page() {
 	return false;
 }
 
+/**
+ * Is the current page the Register page?
+ *
+ * Eg http://example.com/register/.
+ *
+ * @return bool True if the current page is the Register page.
+ */
 function bp_is_register_page() {
 	if ( bp_is_current_component( 'register' ) )
 		return true;
@@ -1585,14 +2275,13 @@ function bp_is_register_page() {
 }
 
 /**
- * Use the above is_() functions to output a body class for each scenario
+ * Customize the body class, according to the currently displayed BP content.
  *
- * @package BuddyPress
- * @subpackage Core Template
+ * Uses the above is_() functions to output a body class for each scenario.
  *
- * @param array $wp_classes The body classes coming from WP
- * @param array $custom_classes Classes that were passed to get_body_class()
- * @return array $classes The BP-adjusted body classes
+ * @param array $wp_classes The body classes coming from WP.
+ * @param array $custom_classes Classes that were passed to get_body_class().
+ * @return array $classes The BP-adjusted body classes.
  */
 function bp_the_body_class() {
 	echo bp_get_the_body_class();
@@ -1683,9 +2372,6 @@ function bp_the_body_class() {
 		if ( bp_is_user_groups_activity() )
 			$bp_classes[] = 'groups-activity';
 
-		if ( is_user_logged_in() )
-			$bp_classes[] = 'logged-in';
-
 		/** Messages **********************************************************/
 
 		if ( bp_is_messages_inbox() )
@@ -1757,31 +2443,14 @@ function bp_the_body_class() {
 			$bp_classes[] = bp_current_action();
 		}
 
-		/** is_buddypress *****************************************************/
+		/** Clean up ***********************************************************/
 
 		// Add BuddyPress class if we are within a BuddyPress page
 		if ( ! bp_is_blog_page() ) {
 			$bp_classes[] = 'buddypress';
 		}
 
-		/** Clean up***********************************************************/
-
-		// We don't want WordPress blog classes to appear on non-blog pages.
-		if ( !bp_is_blog_page() ) {
-
-			// Observe WP custom background body class
-			if ( in_array( 'custom-background', (array) $wp_classes ) )
-				$bp_classes[] = 'custom-background';
-
-			// Preserve any custom classes already set
-			if ( !empty( $custom_classes ) ) {
-				$wp_classes = (array) $custom_classes;
-			} else {
-				$wp_classes = array();
-			}
-		}
-
-		// Merge WP classes with BP classes and remove any duplicates
+		// Merge WP classes with BuddyPress classes and remove any duplicates
 		$classes = array_unique( array_merge( (array) $bp_classes, (array) $wp_classes ) );
 
 		return apply_filters( 'bp_get_the_body_class', $classes, $bp_classes, $wp_classes, $custom_classes );
@@ -1791,13 +2460,16 @@ function bp_the_body_class() {
 /**
  * Sort BuddyPress nav menu items by their position property.
  *
- * This is an internal convenience function and it will probably be removed in a later release. Do not use.
+ * This is an internal convenience function and it will probably be removed in
+ * a later release. Do not use.
  *
  * @access private
- * @param array $a First item
- * @param array $b Second item
- * @return int Returns an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @param array $a First item.
+ * @param array $b Second item.
+ * @return int Returns an integer less than, equal to, or greater than zero if
+ *         the first argument is considered to be respectively less than, equal to, or greater than the second.
  */
 function _bp_nav_menu_sort( $a, $b ) {
 	if ( $a["position"] == $b["position"] )
@@ -1811,10 +2483,11 @@ function _bp_nav_menu_sort( $a, $b ) {
 }
 
 /**
- * Get an array of all the items registered in the primary and secondary BuddyPress navigation menus
+ * Get the items registered in the primary and secondary BuddyPress navigation menus.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @return array
- * @since BuddyPress (1.7)
+ * @return array A multidimensional array of all navigation items.
  */
 function bp_get_nav_menu_items() {
 	$menus = $selected_menus = array();
@@ -1888,34 +2561,40 @@ function bp_get_nav_menu_items() {
 }
 
 /**
- * Displays a navigation menu.
- *
- * @param string|array $args Optional arguments:
- *  - before           Text before the link text.
- *  - container        Whether to wrap the ul, and what to wrap it with.
- *                     Defaults to div.
- *  - container_class  The class that is applied to the container. Defaults to
- *                     'menu-bp-container'.
- *  - container_id     The ID that is applied to the container. Defaults to
- *                     blank.
- *  - depth            How many levels of the hierarchy are to be included. 0
- *                     means all. Defaults to 0.
- *  - echo             Whether to echo the menu or return it. Defaults to echo.
- *  - fallback_cb      If the menu doesn't exists, a callback function will
- *                     fire. Defaults to false (no fallback).
- *  - items_wrap       How the list items should be wrapped. Defaults to a ul
- *                     with an id and class. Uses printf() format with numbered
- *                     placeholders.
- *  - link_after       Text after the link.
- *  - link_before      Text before the link.
- *  - menu_class       CSS class to use for the ul element which forms the menu.
- *                     Defaults to 'menu'.
- *  - menu_id          The ID that is applied to the ul element which forms the
- *                     menu. Defaults to 'menu-bp', incremented.
- *  - walker           Allows a custom walker to be specified. Defaults to
- *                     'BP_Walker_Nav_Menu'.
- *
- * @since BuddyPress (1.7)
+ * Display a navigation menu.
+ *
+ * @since BuddyPress (1.7.0)
+ *
+ * @param string|array $args {
+ *     An array of optional arguments.
+ *     @type string $after Text after the link text. Default: ''.
+ *     @type string $before Text before the link text. Default: ''.
+ *     @type string $container The name of the element to wrap the navigation
+ *           with. 'div' or 'nav'. Default: 'div'.
+ *     @type string $container_class The class that is applied to the container.
+ *           Default: 'menu-bp-container'.
+ *     @type string $container_id The ID that is applied to the container.
+ *           Default: ''.
+ *     @type int depth How many levels of the hierarchy are to be included. 0
+ *           means all. Default: 0.
+ *     @type bool $echo True to echo the menu, false to return it.
+ *           Default: true.
+ *     @type bool $fallback_cb If the menu doesn't exist, should a callback
+ *           function be fired? Default: false (no fallback).
+ *     @type string $items_wrap How the list items should be wrapped. Should be
+ *           in the form of a printf()-friendly string, using numbered
+ *           placeholders. Default: '<ul id="%1$s" class="%2$s">%3$s</ul>'.
+ *     @type string $link_after Text after the link. Default: ''.
+ *     @type string $link_before Text before the link. Default: ''.
+ *     @type string $menu_class CSS class to use for the <ul> element which
+ *           forms the menu. Default: 'menu'.
+ *     @type string $menu_id The ID that is applied to the <ul> element which
+ *           forms the menu. Default: 'menu-bp', incremented.
+ *     @type string $walker Allows a custom walker class to be specified.
+ *           Default: 'BP_Walker_Nav_Menu'.
+ * }
+ * @return string|null If $echo is false, returns a string containing the nav
+ *         menu markup.
  */
 function bp_nav_menu( $args = array() ) {
 	static $menu_id_slugs = array();
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-theme-compatibility.php b/wp-content/plugins/buddypress/bp-core/bp-core-theme-compatibility.php
index c9c126efbe14a3771bdeb9278b58fe0134ec6acd..df8f37ec632d5c8fa74903b0eb06b6f0f45dcb2c 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-theme-compatibility.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-theme-compatibility.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Core Theme Compatibility
+ * BuddyPress Core Theme Compatibility.
  *
  * @package BuddyPress
  * @subpackage ThemeCompatibility
@@ -25,27 +25,33 @@ if ( !defined( 'ABSPATH' ) ) exit;
 /** Base Class ****************************************************************/
 
 /**
- * Theme Compatibility base class
+ * Theme Compatibility base class.
  *
  * This is only intended to be extended, and is included here as a basic guide
- * for future Theme Packs to use. @link BP_Legacy is a good example of
+ * for future Theme Packs to use. {@link BP_Legacy} is a good example of
  * extending this class.
  *
- * @since BuddyPress (1.7)
- * @todo We should probably do something similar to BP_Component::start()
+ * @since BuddyPress (1.7.0)
+ *
+ * @todo We should probably do something similar to BP_Component::start().
+ * @todo If this is only intended to be extended, it should be abstract.
+ *
+ * @param array $properties {
+ *     An array of properties describing the theme compat package.
+ *     @type string $id ID of the package. Must be unique.
+ *     @type string $name Name of the theme. This should match the name given
+ *           in style.css.
+ *     @type string $version Theme version. Used for busting script and style
+ *           browser caches.
+ *     @type string $dir Filesystem path of the theme.
+ *     @type string $url Base URL of the theme.
+ * }
  */
 class BP_Theme_Compat {
 
 	/**
-	 * Should be like:
+	 * Template package properties, as passed to the constructor.
 	 *
-	 * array(
-	 *     'id'      => ID of the theme (should be unique)
-	 *     'name'    => Name of the theme (should match style.css)
-	 *     'version' => Theme version for cache busting scripts and styling
-	 *     'dir'     => Path to theme
-	 *     'url'     => URL to theme
-	 * );
 	 * @var array
 	 */
 	protected $_data = array();
@@ -53,42 +59,23 @@ class BP_Theme_Compat {
 	/**
 	 * Pass the $properties to the object on creation.
 	 *
-	 * @since BuddyPress (1.7)
-	 * @param array $properties
+	 * @since BuddyPress (1.7.0)
 	 */
     	public function __construct( Array $properties = array() ) {
 		$this->_data = $properties;
 	}
 
-
 	/**
-	 * Themes shoud use this method in their constructor.
-	 *
-	 * In this method, we check all types of conditions where theme compatibility
-	 * should *not* run.
+	 * Set up the BuddyPress-specific theme compat methods.
 	 *
-	 * If we pass all conditions, then we setup some additional methods to use.
+	 * Themes shoud use this method in their constructor.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	protected function start() {
-
-		// If the theme supports 'buddypress', bail.
-		if ( current_theme_supports( 'buddypress' ) ) {
+		// Sanity check
+		if ( ! bp_use_theme_compat_with_current_theme() ) {
 			return;
-
-		// If the theme doesn't support BP, do some additional checks
-		} else {
-			// Bail if theme is a derivative of bp-default
-			if ( in_array( 'bp-default', array( get_template(), get_stylesheet() ) ) ) {
-				return;
-			}
-
-			// Bruteforce check for a BP template
-			// Examples are clones of bp-default
-			if ( locate_template( 'members/members-loop.php', false, false ) ) {
-				return;
-			}
 		}
 
 		// Setup methods
@@ -97,26 +84,33 @@ class BP_Theme_Compat {
 	}
 
 	/**
-	 * Meant to be extended in your class.
+	 * Set up global data for your template package.
 	 *
-	 * @since BuddyPress (1.7)
+	 * Meant to be overridden in your class. See
+	 * {@link BP_Legacy::setup_globals()} for an example.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 */
 	protected function setup_globals() {}
 
 	/**
-	 * Meant to be extended in your class.
+	 * Set up theme hooks for your template package.
+	 *
+	 * Meant to be overridden in your class. See
+	 * {@link BP_Legacy::setup_actions()} for an example.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	protected function setup_actions() {}
 
 	/**
 	 * Set a theme's property.
 	 *
-	 * @since BuddyPress (1.7)
-	 * @param string $property
-	 * @param mixed $value
-	 * @return mixed
+	 * @since BuddyPress (1.7.0)
+	 *
+	 * @param string $property Property name.
+	 * @param mixed $value Property value.
+	 * @return bool True on success, false on failure.
 	 */
 	public function __set( $property, $value ) {
 		return $this->_data[$property] = $value;
@@ -125,10 +119,11 @@ class BP_Theme_Compat {
 	/**
 	 * Get a theme's property.
 	 *
-	 * @since BuddyPress (1.7)
-	 * @param string $property
-	 * @param mixed $value
-	 * @return mixed
+	 * @since BuddyPress (1.7.0)
+	 *
+	 * @param string $property Property name.
+	 * @return mixed The value of the property if it exists, otherwise an
+	 *         empty string.
 	 */
 	public function __get( $property ) {
 		return array_key_exists( $property, $this->_data ) ? $this->_data[$property] : '';
@@ -138,10 +133,11 @@ class BP_Theme_Compat {
 /** Functions *****************************************************************/
 
 /**
- * Setup the default theme compat theme
+ * Set up the default theme compat theme.
  *
- * @since BuddyPress (1.7)
- * @param BP_Theme_Compat $theme
+ * @since BuddyPress (1.7.0)
+ *
+ * @param string $theme Optional. The unique ID identifier of a theme package.
  */
 function bp_setup_theme_compat( $theme = '' ) {
 	$bp = buddypress();
@@ -156,80 +152,159 @@ function bp_setup_theme_compat( $theme = '' ) {
 }
 
 /**
- * Gets the name of the BuddyPress compatable theme used, in the event the
- * currently active WordPress theme does not explicitly support BuddyPress.
+ * Get the ID of the theme package being used.
+ *
  * This can be filtered or set manually. Tricky theme authors can override the
  * default and include their own BuddyPress compatability layers for their themes.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
  * @uses apply_filters()
- * @return string
+ *
+ * @return string ID of the theme package in use.
  */
 function bp_get_theme_compat_id() {
 	return apply_filters( 'bp_get_theme_compat_id', buddypress()->theme_compat->theme->id );
 }
 
 /**
- * Gets the name of the BuddyPress compatable theme used, in the event the
- * currently active WordPress theme does not explicitly support BuddyPress.
+ * Get the name of the theme package being used.
+ *
  * This can be filtered or set manually. Tricky theme authors can override the
  * default and include their own BuddyPress compatability layers for their themes.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
  * @uses apply_filters()
- * @return string
+ *
+ * @return string Name of the theme package currently in use.
  */
 function bp_get_theme_compat_name() {
 	return apply_filters( 'bp_get_theme_compat_name', buddypress()->theme_compat->theme->name );
 }
 
 /**
- * Gets the version of the BuddyPress compatable theme used, in the event the
- * currently active WordPress theme does not explicitly support BuddyPress.
+ * Get the version of the theme package being used.
+ *
  * This can be filtered or set manually. Tricky theme authors can override the
  * default and include their own BuddyPress compatability layers for their themes.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
  * @uses apply_filters()
- * @return string
+ *
+ * @return string The version string of the theme package currently in use.
  */
 function bp_get_theme_compat_version() {
 	return apply_filters( 'bp_get_theme_compat_version', buddypress()->theme_compat->theme->version );
 }
 
 /**
- * Gets the BuddyPress compatable theme used in the event the currently active
- * WordPress theme does not explicitly support BuddyPress. This can be filtered,
+ * Get the absolute path of the theme package being used.
+ *
  * or set manually. Tricky theme authors can override the default and include
  * their own BuddyPress compatability layers for their themes.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
  * @uses apply_filters()
- * @return string
+ *
+ * @return string The absolute path of the theme package currently in use.
  */
 function bp_get_theme_compat_dir() {
 	return apply_filters( 'bp_get_theme_compat_dir', buddypress()->theme_compat->theme->dir );
 }
 
 /**
- * Gets the BuddyPress compatable theme used in the event the currently active
- * WordPress theme does not explicitly support BuddyPress. This can be filtered,
- * or set manually. Tricky theme authors can override the default and include
- * their own BuddyPress compatability layers for their themes.
+ * Get the URL of the theme package being used.
+ *
+ * This can be filtered, or set manually. Tricky theme authors can override
+ * the default and include their own BuddyPress compatability layers for their
+ * themes.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
  * @uses apply_filters()
- * @return string
+ *
+ * @return string URL of the theme package currently in use.
  */
 function bp_get_theme_compat_url() {
 	return apply_filters( 'bp_get_theme_compat_url', buddypress()->theme_compat->theme->url );
 }
 
 /**
- * Gets true/false if the current, loaded page uses theme compatibility
+ * Should we use theme compat for this theme?
  *
- * @since BuddyPress (1.7)
- * @return bool
+ * If the current theme's need for theme compat hasn't yet been detected, we
+ * do so using bp_detect_theme_compat_with_current_theme().
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @uses bp_detect_theme_compat_with_current_theme()
+ *
+ * @return bool True if the current theme needs theme compatibility.
+ */
+function bp_use_theme_compat_with_current_theme() {
+	if ( ! isset( buddypress()->theme_compat->use_with_current_theme ) ) {
+		bp_detect_theme_compat_with_current_theme();
+	}
+
+	return apply_filters( 'bp_use_theme_compat_with_current_theme', buddypress()->theme_compat->use_with_current_theme );
+}
+
+/**
+ * Set our flag to determine whether theme compat should be enabled.
+ *
+ * Theme compat is disabled when a theme meets one of the following criteria:
+ * 1) It declares BP support with add_theme_support( 'buddypress' )
+ * 2) It is bp-default, or a child theme of bp-default
+ * 3) A legacy template is found at members/members-loop.php. This is a
+ *    fallback check for themes that were derived from bp-default, and have
+ *    not been updated for BP 1.7+; we make the assumption that any theme in
+ *    this category will have the members-loop.php template, and so use its
+ *    presence as an indicator that theme compatibility is not required
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return bool True if the current theme needs theme compatibility.
+ */
+function bp_detect_theme_compat_with_current_theme() {
+	if ( isset( buddypress()->theme_compat->use_with_current_theme ) ) {
+		return buddypress()->theme_compat->use_with_current_theme;
+	}
+
+	// theme compat enabled by default
+	$theme_compat = true;
+
+	// If the theme supports 'buddypress', bail.
+	if ( current_theme_supports( 'buddypress' ) ) {
+		$theme_compat = false;
+
+	// If the theme doesn't support BP, do some additional checks
+	} else {
+		// Bail if theme is a derivative of bp-default
+		if ( in_array( 'bp-default', array( get_template(), get_stylesheet() ) ) ) {
+			$theme_compat = false;
+
+		// Bruteforce check for a BP template
+		// Examples are clones of bp-default
+		} else if ( locate_template( 'members/members-loop.php', false, false ) ) {
+			$theme_compat = false;
+		}
+	}
+
+	// set a flag in the buddypress() singleton so we don't have to run this again
+	buddypress()->theme_compat->use_with_current_theme = $theme_compat;
+
+	return $theme_compat;
+}
+
+/**
+ * Is the current page using theme compatibility?
+ *
+ * @since BuddyPress (1.7.0)
+ *
+ * @return bool True if the current page uses theme compatibility.
  */
 function bp_is_theme_compat_active() {
 	$bp = buddypress();
@@ -241,11 +316,12 @@ function bp_is_theme_compat_active() {
 }
 
 /**
- * Sets true/false if page is currently inside theme compatibility
+ * Set the flag that tells whether the current page is using theme compatibility.
  *
- * @since BuddyPress (1.7)
- * @param bool $set
- * @return bool
+ * @since BuddyPress (1.7.0)
+ *
+ * @param bool $set True to set the flag to true, false to set it to false.
+ * @return bool Returns the value of $set.
  */
 function bp_set_theme_compat_active( $set = true ) {
 	buddypress()->theme_compat->active = $set;
@@ -254,12 +330,15 @@ function bp_set_theme_compat_active( $set = true ) {
 }
 
 /**
- * Set the theme compat templates global
+ * Set the theme compat templates global.
  *
  * Stash possible template files for the current query. Useful if plugins want
  * to override them, or see what files are being scanned for inclusion.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @param array $templates The template stack.
+ * @return array The template stack (value of $templates).
  */
 function bp_set_theme_compat_templates( $templates = array() ) {
 	buddypress()->theme_compat->templates = $templates;
@@ -268,12 +347,15 @@ function bp_set_theme_compat_templates( $templates = array() ) {
 }
 
 /**
- * Set the theme compat template global
+ * Set the theme compat template global.
  *
  * Stash the template file for the current query. Useful if plugins want
  * to override it, or see what file is being included.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @param string $template The template currently in use.
+ * @return string The template currently in use (value of $template).
  */
 function bp_set_theme_compat_template( $template = '' ) {
 	buddypress()->theme_compat->template = $template;
@@ -282,12 +364,15 @@ function bp_set_theme_compat_template( $template = '' ) {
 }
 
 /**
- * Set the theme compat original_template global
+ * Set the theme compat original_template global.
  *
  * Stash the original template file for the current query. Useful for checking
  * if BuddyPress was able to find a more appropriate template.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @param string $template The template originally selected by WP.
+ * @return string The template originally selected by WP (value of $template).
  */
 function bp_set_theme_compat_original_template( $template = '' ) {
 	buddypress()->theme_compat->original_template = $template;
@@ -296,12 +381,13 @@ function bp_set_theme_compat_original_template( $template = '' ) {
 }
 
 /**
- * Set the theme compat original_template global
+ * Check whether a given template is the one that WP originally selected to display current page.
  *
- * Stash the original template file for the current query. Useful for checking
- * if BuddyPress was able to find a more appropriate template.
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
+ * @param string $template The template name to check.
+ * @return bool True if the value of $template is the same as the
+ *         "original_template" originally selected by WP. Otherwise false.
  */
 function bp_is_theme_compat_original_template( $template = '' ) {
 	$bp = buddypress();
@@ -313,23 +399,18 @@ function bp_is_theme_compat_original_template( $template = '' ) {
 }
 
 /**
- * Register a new BuddyPress theme package to the active theme packages array
- *
- * The $theme parameter is an array, which takes the following values:
- *
- *  'id'      - ID for your theme package; should be alphanumeric only
- *  'name'    - Name of your theme package
- *  'version' - Version of your theme package
- *  'dir'     - Directory where your theme package resides
- *  'url'     - URL where your theme package resides
+ * Register a new BuddyPress theme package in the active theme packages array.
  *
  * For an example of how this function is used, see:
  * {@link BuddyPress::register_theme_packages()}.
  *
  * @since BuddyPress (1.7)
  *
- * @param array $theme The theme package arguments. See phpDoc for more details.
+ * @see BP_Theme_Compat for a description of the $theme parameter arguments.
+ *
+ * @param array $theme See {@link BP_Theme_Compat}.
  * @param bool $override If true, overrides whatever package is currently set.
+ *        Default: true.
  */
 function bp_register_theme_package( $theme = array(), $override = true ) {
 
@@ -354,13 +435,20 @@ function bp_register_theme_package( $theme = array(), $override = true ) {
 }
 
 /**
- * This fun little function fills up some WordPress globals with dummy data to
- * stop your average page template from complaining about it missing.
+ * Populate various WordPress globals with dummy data to prevent errors.
  *
- * @since BuddyPress (1.7)
- * @global WP_Query $wp_query
- * @global object $post
- * @param array $args
+ * This dummy data is necessary because theme compatibility essentially fakes
+ * WordPress into thinking that there is content where, in fact, there is none
+ * (at least, no WordPress post content). By providing dummy data, we ensure
+ * that template functions - things like is_page() - don't throw errors.
+ *
+ * @since BuddyPress (1.7.0)
+ *
+ * @global WP_Query $wp_query WordPress database access object.
+ * @global object $post Current post object.
+ *
+ * @param array $args Array of optional arguments. Arguments parallel the
+ *        properties of {@link WP_Post}; see that class for more details.
  */
 function bp_theme_compat_reset_post( $args = array() ) {
 	global $wp_query, $post;
@@ -471,32 +559,38 @@ function bp_theme_compat_reset_post( $args = array() ) {
 }
 
 /**
- * Reset main query vars and filter 'the_content' to output a BuddyPress
- * template part as needed.
- *
- * @since BuddyPress (1.7)
- *
- * @param string $template
- * @uses bp_is_single_user() To check if page is single user
- * @uses bp_get_single_user_template() To get user template
- * @uses bp_is_single_user_edit() To check if page is single user edit
- * @uses bp_get_single_user_edit_template() To get user edit template
- * @uses bp_is_single_view() To check if page is single view
- * @uses bp_get_single_view_template() To get view template
- * @uses bp_is_forum_edit() To check if page is forum edit
- * @uses bp_get_forum_edit_template() To get forum edit template
- * @uses bp_is_topic_merge() To check if page is topic merge
- * @uses bp_get_topic_merge_template() To get topic merge template
- * @uses bp_is_topic_split() To check if page is topic split
- * @uses bp_get_topic_split_template() To get topic split template
- * @uses bp_is_topic_edit() To check if page is topic edit
- * @uses bp_get_topic_edit_template() To get topic edit template
- * @uses bp_is_reply_edit() To check if page is reply edit
- * @uses bp_get_reply_edit_template() To get reply edit template
- * @uses bp_set_theme_compat_template() To set the global theme compat template
+ * Reset main query vars and filter 'the_content' to output a BuddyPress template part as needed.
+ *
+ * @since BuddyPress (1.7.0)
+ *
+ * @uses bp_is_single_user() To check if page is single user.
+ * @uses bp_get_single_user_template() To get user template.
+ * @uses bp_is_single_user_edit() To check if page is single user edit.
+ * @uses bp_get_single_user_edit_template() To get user edit template.
+ * @uses bp_is_single_view() To check if page is single view.
+ * @uses bp_get_single_view_template() To get view template.
+ * @uses bp_is_forum_edit() To check if page is forum edit.
+ * @uses bp_get_forum_edit_template() To get forum edit template.
+ * @uses bp_is_topic_merge() To check if page is topic merge.
+ * @uses bp_get_topic_merge_template() To get topic merge template.
+ * @uses bp_is_topic_split() To check if page is topic split.
+ * @uses bp_get_topic_split_template() To get topic split template.
+ * @uses bp_is_topic_edit() To check if page is topic edit.
+ * @uses bp_get_topic_edit_template() To get topic edit template.
+ * @uses bp_is_reply_edit() To check if page is reply edit.
+ * @uses bp_get_reply_edit_template() To get reply edit template.
+ * @uses bp_set_theme_compat_template() To set the global theme compat template.
+ *
+ * @param string $template Template name.
+ * @return string $template Template name.
  */
 function bp_template_include_theme_compat( $template = '' ) {
 
+	// If the current theme doesn't need theme compat, bail at this point.
+	if ( ! bp_use_theme_compat_with_current_theme() ) {
+		return $template;
+	}
+
 	/**
 	 * Use this action to execute code that will communicate to BuddyPress's
 	 * theme compatibility layer whether or not we're replacing the_content()
@@ -540,13 +634,16 @@ function bp_template_include_theme_compat( $template = '' ) {
 }
 
 /**
+ * Conditionally replace 'the_content'.
+ *
  * Replaces the_content() if the post_type being displayed is one that would
  * normally be handled by BuddyPress, but proper single page templates do not
  * exist in the currently active theme.
  *
- * @since BuddyPress (1.7)
- * @param string $content
- * @return string
+ * @since BuddyPress (1.7.0)
+ *
+ * @param string $content Original post content.
+ * @return string $content Post content, potentially modified.
  */
 function bp_replace_the_content( $content = '' ) {
 
@@ -579,10 +676,12 @@ function bp_replace_the_content( $content = '' ) {
 }
 
 /**
- * Are we replacing the_content
+ * Are we currently replacing the_content?
  *
- * @since BuddyPress (1.8)
- * @return bool
+ * @since BuddyPress (1.8.0)
+ *
+ * @return bool True if the_content is currently in the process of being
+ *         filtered and replaced.
  */
 function bp_do_theme_compat() {
 	return (bool) ( ! bp_is_template_included() && in_the_loop() && bp_is_theme_compat_active() );
@@ -591,15 +690,21 @@ function bp_do_theme_compat() {
 /** Filters *******************************************************************/
 
 /**
- * Removes all filters from a WordPress filter, and stashes them in the $bp
- * global in the event they need to be restored later.
+ * Remove all filters from a WordPress filter hook.
+ *
+ * Removed filters are stashed in the $bp global, in case they need to be
+ * restored later.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
  * @global WP_filter $wp_filter
  * @global array $merged_filters
- * @param string $tag
- * @param int $priority
- * @return bool
+ *
+ * @param string $tag The filter tag to remove filters from.
+ * @param int $priority Optional. If present, only those callbacks attached
+ *        at a given priority will be removed. Otherwise, all callbacks
+ *        attached to the tag will be removed, regardless of priority.
+ * @return bool True on success.
  */
 function bp_remove_all_filters( $tag, $priority = false ) {
 	global $wp_filter, $merged_filters;
@@ -643,15 +748,19 @@ function bp_remove_all_filters( $tag, $priority = false ) {
 }
 
 /**
- * Restores filters from the $bp global that were removed using
- * bp_remove_all_filters()
+ * Restore filters that were removed using bp_remove_all_filters().
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
  * @global WP_filter $wp_filter
  * @global array $merged_filters
- * @param string $tag
- * @param int $priority
- * @return bool
+ *
+ * @param string $tag The tag to which filters should be restored.
+ * @param int $priority Optional. If present, only those filters that were
+ *        originally attached to the tag with $priority will be restored.
+ *        Otherwise, all available filters will be restored, regardless of
+ *        priority.
+ * @return bool True on success.
  */
 function bp_restore_all_filters( $tag, $priority = false ) {
 	global $wp_filter, $merged_filters;
@@ -695,12 +804,13 @@ function bp_restore_all_filters( $tag, $priority = false ) {
 }
 
 /**
- * Force comments_status to 'closed' for BuddyPress post types
+ * Force comments_status to 'closed' for BuddyPress post types.
  *
- * @since BuddyPress (1.7)
- * @param bool $open True if open, false if closed
- * @param int $post_id ID of the post to check
- * @return bool True if open, false if closed
+ * @since BuddyPress (1.7.0)
+ *
+ * @param bool $open True if open, false if closed.
+ * @param int $post_id ID of the post to check.
+ * @return bool True if open, false if closed.
  */
 function bp_comments_open( $open, $post_id = 0 ) {
 
@@ -709,3 +819,61 @@ function bp_comments_open( $open, $post_id = 0 ) {
 	// Allow override of the override
 	return apply_filters( 'bp_force_comment_status', $retval, $open, $post_id );
 }
+
+/**
+ * Do not allow {@link comments_template()} to render during theme compatibility.
+ *
+ * When theme compatibility sets the 'is_page' flag to true via
+ * {@link bp_theme_compat_reset_post()}, themes that use comments_template()
+ * in their page template will run.
+ *
+ * To prevent comments_template() from rendering, we set the 'is_page' and
+ * 'is_single' flags to false since that function looks at these conditionals
+ * before querying the database for comments and loading the comments template.
+ *
+ * This is done during the output buffer as late as possible to prevent any
+ * wonkiness.
+ *
+ * @since BuddyPress (1.9.2)
+ *
+ * @param string $retval The current post content.
+ */
+function bp_theme_compat_toggle_is_page( $retval = '' ) {
+	global $wp_query;
+
+	$wp_query->is_single = false;
+	$wp_query->is_page   = false;
+
+	// Set a switch so we know that we've toggled these WP_Query properties
+	buddypress()->theme_compat->is_page_toggled = true;
+
+	return $retval;
+}
+add_filter( 'bp_replace_the_content', 'bp_theme_compat_toggle_is_page', 9999 );
+
+/**
+ * Restores the 'is_single' and 'is_page' flags if toggled by BuddyPress.
+ *
+ * @since BuddyPress (1.9.2)
+ *
+ * @see bp_theme_compat_toggle_is_page()
+ * @param object $query The WP_Query object.
+ */
+function bp_theme_compat_loop_end( $query ) {
+
+	// Get BuddyPress
+	$bp = buddypress();
+
+	// Bail if page is not toggled
+	if ( ! isset( $bp->theme_compat->is_page_toggled ) ) {
+		return;
+	}
+
+	// Revert our toggled WP_Query properties
+	$query->is_single = true;
+	$query->is_page   = true;
+
+	// Unset our switch
+	unset( $bp->theme_compat->is_page_toggled );
+}
+add_action( 'loop_end', 'bp_theme_compat_loop_end' );
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-update.php b/wp-content/plugins/buddypress/bp-core/bp-core-update.php
index 08c6024c9007768ef94ef18f5ac0049a0e4b8738..8b1f30e10c8cab8d36216949fbb12a2281adc493 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-update.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-update.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Updater
+ * BuddyPress Updater.
  *
  * @package BuddyPress
  * @subpackage Updater
@@ -11,26 +11,34 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * If there is no raw DB version, this is the first installation
+ * Is this a fresh installation of BuddyPress?
  *
- * @since BuddyPress (1.7)
+ * If there is no raw DB version, we infer that this is the first installation.
+ *
+ * @since BuddyPress (1.7.0)
  *
  * @uses get_option()
- * @uses bp_get_db_version() To get BuddyPress's database version
- * @return bool True if update, False if not
+ * @uses bp_get_db_version() To get BuddyPress's database version.
+ *
+ * @return bool True if this is a fresh BP install, otherwise false.
  */
 function bp_is_install() {
 	return ! bp_get_db_version_raw();
 }
 
 /**
- * Compare the BuddyPress version to the DB version to determine if updating
+ * Is this a BuddyPress update?
  *
- * @since BuddyPress (1.6)
+ * Determined by comparing the registered BuddyPress version to the version
+ * number stored in the database. If the registered version is greater, it's
+ * an update.
+ *
+ * @since BuddyPress (1.6.0)
  *
  * @uses get_option()
- * @uses bp_get_db_version() To get BuddyPress's database version
- * @return bool True if update, False if not
+ * @uses bp_get_db_version() To get BuddyPress's database version.
+ *
+ * @return bool True if update, otherwise false.
  */
 function bp_is_update() {
 
@@ -46,12 +54,13 @@ function bp_is_update() {
 }
 
 /**
- * Determine if BuddyPress is being activated
+ * Determine whether BuddyPress is in the process of being activated.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
  * @uses buddypress()
- * @return bool True if activating BuddyPress, false if not
+ *
+ * @return bool True if activating BuddyPress, false if not.
  */
 function bp_is_activation( $basename = '' ) {
 	$bp     = buddypress();
@@ -90,12 +99,13 @@ function bp_is_activation( $basename = '' ) {
 }
 
 /**
- * Determine if BuddyPress is being deactivated
+ * Determine whether BuddyPress is in the process of being deactivated.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
  * @uses buddypress()
- * @return bool True if deactivating BuddyPress, false if not
+ *
+ * @return bool True if deactivating BuddyPress, false if not.
  */
 function bp_is_deactivation( $basename = '' ) {
 	$bp     = buddypress();
@@ -134,22 +144,21 @@ function bp_is_deactivation( $basename = '' ) {
 }
 
 /**
- * Update the DB to the latest version
+ * Update the BP version stored in the database to the current version.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @uses update_option()
- * @uses bp_get_db_version() To get BuddyPress's database version
- * @uses bp_update_option() To update BuddyPress's database version
+ * @uses bp_get_db_version() To get BuddyPress's database version.
+ * @uses bp_update_option() To update BuddyPress's database version.
  */
 function bp_version_bump() {
 	bp_update_option( '_bp_db_version', bp_get_db_version() );
 }
 
 /**
- * Setup the BuddyPress updater
+ * Set up the BuddyPress updater.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 function bp_setup_updater() {
 
@@ -161,21 +170,31 @@ function bp_setup_updater() {
 }
 
 /**
+ * Initialize an update or installation of BuddyPress.
+ *
  * BuddyPress's version updater looks at what the current database version is,
- * and runs whatever other code is needed.
+ * and runs whatever other code is needed - either the "update" or "install"
+ * code.
  *
- * This is most-often used when the data schema changes, but should also be used
+ * This is most often used when the data schema changes, but should also be used
  * to correct issues with BuddyPress metadata silently on software update.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_version_updater() {
 
 	// Get the raw database version
 	$raw_db_version = (int) bp_get_db_version_raw();
 
-	$default_components = apply_filters( 'bp_new_install_default_components', array( 'activity' => 1, 'members' => 1, 'xprofile' => 1, ) );
-	require_once( BP_PLUGIN_DIR . '/bp-core/admin/bp-core-schema.php' );
+	$default_components = apply_filters( 'bp_new_install_default_components', array(
+		'activity'      => 1,
+		'members'       => 1,
+		'settings'      => 1,
+		'xprofile'      => 1,
+		'notifications' => 1,
+	) );
+
+	require_once( buddypress()->plugin_dir . '/bp-core/admin/bp-core-schema.php' );
 
 	// Install BP schema and activate only Activity and XProfile
 	if ( bp_is_install() ) {
@@ -201,6 +220,21 @@ function bp_version_updater() {
 		if ( $raw_db_version < 6067 ) {
 			bp_update_to_1_6();
 		}
+
+		// 1.9
+		if ( $raw_db_version < 7553 ) {
+			bp_update_to_1_9();
+		}
+
+		// 1.9.2
+		if ( $raw_db_version < 7731 ) {
+			bp_update_to_1_9_2();
+		}
+
+		// 2.0
+		if ( $raw_db_version < 7892 ) {
+			bp_update_to_2_0();
+		}
 	}
 
 	/** All done! *************************************************************/
@@ -210,9 +244,11 @@ function bp_version_updater() {
 }
 
 /**
- * Database update methods based on version numbers
+ * Remove unused metadata from database when upgrading from < 1.5.
  *
- * @since BuddyPress (1.7)
+ * Database update methods based on version numbers.
+ *
+ * @since BuddyPress (1.7.0)
  */
 function bp_update_to_1_5() {
 
@@ -226,9 +262,11 @@ function bp_update_to_1_5() {
 }
 
 /**
- * Database update methods based on version numbers
+ * Remove unused metadata from database when upgrading from < 1.6.
+ *
+ * Database update methods based on version numbers.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_update_to_1_6() {
 
@@ -246,13 +284,129 @@ function bp_update_to_1_6() {
 }
 
 /**
- * Redirect user to BuddyPress's What's New page on activation
+ * Add the notifications component to active components.
+ *
+ * Notifications was added in 1.9.0, and previous installations will already
+ * have the core notifications API active. We need to add the new Notifications
+ * component to the active components option to retain existing functionality.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_update_to_1_9() {
+
+	// Setup hardcoded keys
+	$active_components_key      = 'bp-active-components';
+	$notifications_component_id = 'notifications';
+
+	// Get the active components
+	$active_components          = bp_get_option( $active_components_key );
+
+	// Add notifications
+	if ( ! in_array( $notifications_component_id, $active_components ) ) {
+		$active_components[ $notifications_component_id ] = 1;
+	}
+
+	// Update the active components option
+	bp_update_option( $active_components_key, $active_components );
+}
+
+/**
+ * Perform database updates for BP 1.9.2
+ *
+ * In 1.9, BuddyPress stopped registering its theme directory when it detected
+ * that bp-default (or a child theme) was not currently being used, in effect
+ * deprecating bp-default. However, this ended up causing problems when site
+ * admins using bp-default would switch away from the theme temporarily:
+ * bp-default would no longer be available, with no obvious way (outside of
+ * a manual filter) to restore it. In 1.9.2, we add an option that flags
+ * whether bp-default or a child theme is active at the time of upgrade; if so,
+ * the theme directory will continue to be registered even if the theme is
+ * deactivated temporarily. Thus, new installations will not see bp-default,
+ * but legacy installations using the theme will continue to see it.
+ *
+ * @since BuddyPress (1.9.2)
+ */
+function bp_update_to_1_9_2() {
+	if ( 'bp-default' === get_stylesheet() || 'bp-default' === get_template() ) {
+		update_site_option( '_bp_retain_bp_default', 1 );
+	}
+}
+
+/**
+ * 2.0 update routine.
+ *
+ * - Ensure that the activity tables are installed, for last_activity storage.
+ * - Migrate last_activity data from usermeta to activity table
+ * - Add values for all BuddyPress options to the options table
+ */
+function bp_update_to_2_0() {
+	global $wpdb;
+
+	/** Install activity tables for 'last_activity' ***************************/
+
+	bp_core_install_activity_streams();
+
+	/** Migrate 'last_activity' data ******************************************/
+
+	bp_last_activity_migrate();
+
+	/** Migrate signups data **************************************************/
+
+	if ( ! is_multisite() ) {
+
+		if ( empty( $wpdb->signups ) ) {
+			bp_core_install_signups();
+		}
+
+		$signups = get_users( array(
+			'fields'       => 'all_with_meta',
+			'meta_key'     => 'activation_key',
+			'meta_compare' => 'EXISTS',
+		) );
+
+		if ( empty( $signups ) ) {
+			return;
+		}
+
+		foreach ( $signups as $signup ) {
+			$meta = array();
+
+			if ( bp_is_active( 'xprofile' ) ) {
+				$meta['field_1'] = $signup->display_name;
+			}
+
+			$meta['password'] = $signup->user_pass;
+
+			$user_login = preg_replace( '/\s+/', '', sanitize_user( $signup->user_login, true ) );
+			$user_email = sanitize_email( $signup->user_email );
+
+			BP_Signup::add( array(
+				'user_login'     => $user_login,
+				'user_email'     => $user_email,
+				'registered'     => $signup->user_registered,
+				'activation_key' => $signup->activation_key,
+				'meta'           => $meta
+			) );
+
+			// Deleting these options will remove signups from users count
+			delete_user_option( $signup->ID, 'capabilities' );
+			delete_user_option( $signup->ID, 'user_level'   );
+		}
+	}
+
+	/** Add BP options to the options table ***********************************/
+
+	bp_add_options();
+}
+
+/**
+ * Redirect user to BP's What's New page on first page load after activation.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @internal Used internally to redirect BuddyPress to the about page on activation
+ * @internal Used internally to redirect BuddyPress to the about page on activation.
  *
- * @uses set_transient() To drop the activation transient for 30 seconds
+ * @uses set_transient() To drop the activation transient for 30 seconds.
  */
 function bp_add_activation_redirect() {
 
@@ -273,17 +427,22 @@ function bp_add_activation_redirect() {
 /** Activation Actions ********************************************************/
 
 /**
- * Runs on BuddyPress activation
+ * Fire activation hooks and events.
  *
- * @since BuddyPress (1.6)
+ * Runs on BuddyPress activation.
  *
- * @uses do_action() Calls 'bp_activation' hook
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses do_action() Calls 'bp_activation' hook.
  */
 function bp_activation() {
 
 	// Force refresh theme roots.
 	delete_site_transient( 'theme_roots' );
 
+	// Add options
+	bp_add_options();
+
 	// Use as of (1.6)
 	do_action( 'bp_activation' );
 
@@ -292,11 +451,13 @@ function bp_activation() {
 }
 
 /**
- * Runs on BuddyPress deactivation
+ * Fire deactivation hooks and events.
  *
- * @since BuddyPress (1.6)
+ * Runs on BuddyPress deactivation.
  *
- * @uses do_action() Calls 'bp_deactivation' hook
+ * @since BuddyPress (1.6.0)
+ *
+ * @uses do_action() Calls 'bp_deactivation' hook.
  */
 function bp_deactivation() {
 
@@ -319,11 +480,13 @@ function bp_deactivation() {
 }
 
 /**
- * Runs when uninstalling BuddyPress
+ * Fire uninstall hook.
+ *
+ * Runs when uninstalling BuddyPress.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  *
- * @uses do_action() Calls 'bp_uninstall' hook
+ * @uses do_action() Calls 'bp_uninstall' hook.
  */
 function bp_uninstall() {
 	do_action( 'bp_uninstall' );
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-widgets.php b/wp-content/plugins/buddypress/bp-core/bp-core-widgets.php
index 76f303db5fad0c0ff8c3c0cb89a9a458de01ab76..79bbb6ca2a6f680aed39a0e9cb1b613a0abdbe63 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-widgets.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-widgets.php
@@ -1,19 +1,151 @@
 <?php
+/**
+ * BuddyPress Core Component Widgets.
+ *
+ * @package BuddyPress
+ * @subpackage Core
+ */
+
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
-/* Register widgets for the core component */
+/**
+ * Register bp-core widgets.
+ */
 function bp_core_register_widgets() {
+	add_action('widgets_init', create_function('', 'return register_widget("BP_Core_Login_Widget");') );
 	add_action('widgets_init', create_function('', 'return register_widget("BP_Core_Members_Widget");') );
 	add_action('widgets_init', create_function('', 'return register_widget("BP_Core_Whos_Online_Widget");') );
 	add_action('widgets_init', create_function('', 'return register_widget("BP_Core_Recently_Active_Widget");') );
 }
 add_action( 'bp_register_widgets', 'bp_core_register_widgets' );
 
-/*** MEMBERS WIDGET *****************/
+/**
+ * BuddyPress Login Widget.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+class BP_Core_Login_Widget extends WP_Widget {
+
+	/**
+	 * Constructor method.
+	 */
+	public function __construct() {
+		parent::__construct(
+			false,
+			_x( '(BuddyPress) Log In', 'Title of the login widget', 'buddypress' ),
+			array(
+				'description' => __( 'Show a Log In form to logged-out visitors, and a Log Out link to those who are logged in.', 'buddypress' ),
+				'classname' => 'widget_bp_core_login_widget buddypress widget',
+			)
+		);
+	}
+
+	/**
+	 * Display the login widget.
+	 *
+	 * @see WP_Widget::widget() for description of parameters.
+	 *
+	 * @param array $args Widget arguments.
+	 * @param array $instance Widget settings, as saved by the user.
+	 */
+	public function widget( $args, $instance ) {
+		$title = isset( $instance['title'] ) ? $instance['title'] : '';
+		$title = apply_filters( 'widget_title', $title );
+
+		echo $args['before_widget'];
+
+		echo $args['before_title'] . esc_html( $title ) . $args['after_title']; ?>
+
+		<?php if ( is_user_logged_in() ) : ?>
+
+			<?php do_action( 'bp_before_login_widget_loggedin' ); ?>
+
+			<div class="bp-login-widget-user-avatar">
+				<a href="<?php echo bp_loggedin_user_domain(); ?>">
+					<?php bp_loggedin_user_avatar( 'type=thumb&width=50&height=50' ); ?>
+				</a>
+			</div>
+
+			<div class="bp-login-widget-user-links">
+				<div class="bp-login-widget-user-link"><?php echo bp_core_get_userlink( bp_loggedin_user_id() ); ?></div>
+				<div class="bp-login-widget-user-logout"><a class="logout" href="<?php echo wp_logout_url( wp_guess_url() ); ?>"><?php _e( 'Log Out', 'buddypress' ); ?></a></div>
+			</div>
+
+			<?php do_action( 'bp_after_login_widget_loggedin' ); ?>
+
+		<?php else : ?>
+
+			<?php do_action( 'bp_before_login_widget_loggedout' ); ?>
+
+			<form name="bp-login-form" id="bp-login-widget-form" class="standard-form" action="<?php echo esc_url( site_url( 'wp-login.php', 'login_post' ) ); ?>" method="post">
+				<label for="bp-login-widget-user-login"><?php _e( 'Username', 'buddypress' ); ?></label>
+				<input type="text" name="log" id="bp-login-widget-user-login" class="input" value="" />
+
+				<label for="bp-login-widget-user-pass"><?php _e( 'Password', 'buddypress' ); ?></label>
+				<input type="password" name="pwd" id="bp-login-widget-user-pass" class="input" value=""  />
+
+				<div class="forgetmenot"><label><input name="rememberme" type="checkbox" id="bp-login-widget-rememberme" value="forever" /> <?php _e( 'Remember Me', 'buddypress' ); ?></label></div>
+
+				<input type="submit" name="wp-submit" id="bp-login-widget-submit" value="<?php esc_attr_e( 'Log In', 'buddypress' ); ?>" />
+
+				<?php if ( bp_get_signup_allowed() ) : ?>
+
+					<span class="bp-login-widget-register-link"><?php printf( __( '<a href="%s" title="Register for a new account">Register</a>', 'buddypress' ), bp_get_signup_page() ); ?></span>
+
+				<?php endif; ?>
+
+			</form>
+
+			<?php do_action( 'bp_after_login_widget_loggedout' ); ?>
+
+		<?php endif;
 
+		echo $args['after_widget'];
+	}
+
+	/**
+	 * Update the login widget options.
+	 *
+	 * @param array $new_instance The new instance options.
+	 * @param array $old_instance The old instance options.
+	 * @return array $instance The parsed options to be saved.
+	 */
+	public function update( $new_instance, $old_instance ) {
+		$instance             = $old_instance;
+		$instance['title']    = isset( $new_instance['title'] ) ? strip_tags( $new_instance['title'] ) : '';
+
+		return $instance;
+	}
+
+	/**
+	 * Output the login widget options form.
+	 *
+	 * @param $instance Settings for this widget.
+	 */
+	public function form( $instance = array() ) {
+
+		$settings = wp_parse_args( $instance, array(
+			'title' => '',
+		) ); ?>
+
+		<p>
+			<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'buddypress' ); ?>
+			<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $settings['title'] ); ?>" /></label>
+		</p>
+
+		<?php
+	}
+}
+
+/**
+ * Members Widget.
+ */
 class BP_Core_Members_Widget extends WP_Widget {
 
+	/**
+	 * Constructor method.
+	 */
 	function __construct() {
 		$widget_ops = array(
 			'description' => __( 'A dynamic list of recently active, popular, and newest members', 'buddypress' ),
@@ -23,10 +155,18 @@ class BP_Core_Members_Widget extends WP_Widget {
 
 		if ( is_active_widget( false, false, $this->id_base ) && !is_admin() && !is_network_admin() ) {
 			$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
-			wp_enqueue_script( 'bp_core_widget_members-js', BP_PLUGIN_URL . "bp-core/js/widget-members{$min}.js", array( 'jquery' ), bp_get_version() );
+			wp_enqueue_script( 'bp_core_widget_members-js', buddypress()->plugin_url . "bp-core/js/widget-members{$min}.js", array( 'jquery' ), bp_get_version() );
 		}
 	}
 
+	/**
+	 * Display the Members widget.
+	 *
+	 * @see WP_Widget::widget() for description of parameters.
+	 *
+	 * @param array $args Widget arguments.
+	 * @param array $instance Widget settings, as saved by the user.
+	 */
 	function widget( $args, $instance ) {
 
 		extract( $args );
@@ -42,9 +182,20 @@ class BP_Core_Members_Widget extends WP_Widget {
 
 		echo $before_title
 		   . $title
-		   . $after_title; ?>
+		   . $after_title;
+
+		$members_args = array(
+			'user_id'         => 0,
+			'type'            => $instance['member_default'],
+			'per_page'        => $instance['max_members'],
+			'max'             => $instance['max_members'],
+			'populate_extras' => true,
+			'search_terms'    => false,
+		);
+
+		?>
 
-		<?php if ( bp_has_members( 'user_id=0&type=' . $instance['member_default'] . '&max=' . $instance['max_members'] . '&populate_extras=1' ) ) : ?>
+		<?php if ( bp_has_members( $members_args ) ) : ?>
 			<div class="item-options" id="members-list-options">
 				<a href="<?php bp_members_directory_permalink(); ?>" id="newest-members" <?php if ( $instance['member_default'] == 'newest' ) : ?>class="selected"<?php endif; ?>><?php _e( 'Newest', 'buddypress' ) ?></a>
 				|  <a href="<?php bp_members_directory_permalink(); ?>" id="recently-active-members" <?php if ( $instance['member_default'] == 'active' ) : ?>class="selected"<?php endif; ?>><?php _e( 'Active', 'buddypress' ) ?></a>
@@ -97,6 +248,13 @@ class BP_Core_Members_Widget extends WP_Widget {
 	<?php
 	}
 
+	/**
+	 * Update the Members widget options.
+	 *
+	 * @param array $new_instance The new instance options.
+	 * @param array $old_instance The old instance options.
+	 * @return array $instance The parsed options to be saved.
+	 */
 	function update( $new_instance, $old_instance ) {
 		$instance = $old_instance;
 
@@ -108,6 +266,11 @@ class BP_Core_Members_Widget extends WP_Widget {
 		return $instance;
 	}
 
+	/**
+	 * Output the Members widget options form.
+	 *
+	 * @param $instance Settings for this widget.
+	 */
 	function form( $instance ) {
 		$defaults = array(
 			'title' 	 => __( 'Members', 'buddypress' ),
@@ -147,6 +310,9 @@ class BP_Core_Members_Widget extends WP_Widget {
 
 class BP_Core_Whos_Online_Widget extends WP_Widget {
 
+	/**
+	 * Constructor method.
+	 */
 	function __construct() {
 		$widget_ops = array(
 			'description' => __( 'Avatars of users who are currently online', 'buddypress' ),
@@ -155,6 +321,14 @@ class BP_Core_Whos_Online_Widget extends WP_Widget {
 		parent::__construct( false, $name = _x( "(BuddyPress) Who's Online", 'widget name', 'buddypress' ), $widget_ops );
 	}
 
+	/**
+	 * Display the Who's Online widget.
+	 *
+	 * @see WP_Widget::widget() for description of parameters.
+	 *
+	 * @param array $args Widget arguments.
+	 * @param array $instance Widget settings, as saved by the user.
+	 */
 	function widget($args, $instance) {
 
 		extract( $args );
@@ -164,9 +338,20 @@ class BP_Core_Whos_Online_Widget extends WP_Widget {
 		echo $before_widget;
 		echo $before_title
 		   . $title
-		   . $after_title; ?>
+		   . $after_title;
+
+		$members_args = array(
+			'user_id'         => 0,
+			'type'            => 'online',
+			'per_page'        => $instance['max_members'],
+			'max'             => $instance['max_members'],
+			'populate_extras' => true,
+			'search_terms'    => false,
+		);
+
+		?>
 
-		<?php if ( bp_has_members( 'user_id=0&type=online&per_page=' . $instance['max_members'] . '&max=' . $instance['max_members'] . '&populate_extras=1' ) ) : ?>
+		<?php if ( bp_has_members( $members_args ) ) : ?>
 			<div class="avatar-block">
 				<?php while ( bp_members() ) : bp_the_member(); ?>
 					<div class="item-avatar">
@@ -186,6 +371,13 @@ class BP_Core_Whos_Online_Widget extends WP_Widget {
 	<?php
 	}
 
+	/**
+	 * Update the Who's Online widget options.
+	 *
+	 * @param array $new_instance The new instance options.
+	 * @param array $old_instance The old instance options.
+	 * @return array $instance The parsed options to be saved.
+	 */
 	function update( $new_instance, $old_instance ) {
 		$instance = $old_instance;
 		$instance['title'] = strip_tags( $new_instance['title'] );
@@ -194,6 +386,11 @@ class BP_Core_Whos_Online_Widget extends WP_Widget {
 		return $instance;
 	}
 
+	/**
+	 * Output the Who's Online widget options form.
+	 *
+	 * @param $instance Settings for this widget.
+	 */
 	function form( $instance ) {
 		$defaults = array(
 			'title' => __( "Who's Online", 'buddypress' ),
@@ -216,6 +413,9 @@ class BP_Core_Whos_Online_Widget extends WP_Widget {
 
 class BP_Core_Recently_Active_Widget extends WP_Widget {
 
+	/**
+	 * Constructor method.
+	 */
 	function __construct() {
 		$widget_ops = array(
 			'description' => __( 'Avatars of recently active members', 'buddypress' ),
@@ -224,6 +424,14 @@ class BP_Core_Recently_Active_Widget extends WP_Widget {
 		parent::__construct( false, $name = _x( '(BuddyPress) Recently Active Members', 'widget name', 'buddypress' ), $widget_ops );
 	}
 
+	/**
+	 * Display the Recently Active widget.
+	 *
+	 * @see WP_Widget::widget() for description of parameters.
+	 *
+	 * @param array $args Widget arguments.
+	 * @param array $instance Widget settings, as saved by the user.
+	 */
 	function widget( $args, $instance ) {
 
 		extract( $args );
@@ -233,9 +441,20 @@ class BP_Core_Recently_Active_Widget extends WP_Widget {
 		echo $before_widget;
 		echo $before_title
 		   . $title
-		   . $after_title; ?>
+		   . $after_title;
+
+		$members_args = array(
+			'user_id'         => 0,
+			'type'            => 'active',
+			'per_page'        => $instance['max_members'],
+			'max'             => $instance['max_members'],
+			'populate_extras' => true,
+			'search_terms'    => false,
+		);
+
+		?>
 
-		<?php if ( bp_has_members( 'user_id=0&type=active&per_page=' . $instance['max_members'] . '&max=' . $instance['max_members'] . '&populate_extras=1' ) ) : ?>
+		<?php if ( bp_has_members( $members_args ) ) : ?>
 			<div class="avatar-block">
 				<?php while ( bp_members() ) : bp_the_member(); ?>
 					<div class="item-avatar">
@@ -255,6 +474,13 @@ class BP_Core_Recently_Active_Widget extends WP_Widget {
 	<?php
 	}
 
+	/**
+	 * Update the Recently Active widget options.
+	 *
+	 * @param array $new_instance The new instance options.
+	 * @param array $old_instance The old instance options.
+	 * @return array $instance The parsed options to be saved.
+	 */
 	function update( $new_instance, $old_instance ) {
 		$instance = $old_instance;
 		$instance['title'] = strip_tags( $new_instance['title'] );
@@ -263,9 +489,14 @@ class BP_Core_Recently_Active_Widget extends WP_Widget {
 		return $instance;
 	}
 
+	/**
+	 * Output the Recently Active widget options form.
+	 *
+	 * @param $instance Settings for this widget.
+	 */
 	function form( $instance ) {
 		$defaults = array(
-			'title' => 'Recently Active Members',
+			'title' => __( 'Recently Active Members', 'buddypress' ),
 			'max_members' => 15
 		);
 		$instance = wp_parse_args( (array) $instance, $defaults );
@@ -281,8 +512,9 @@ class BP_Core_Recently_Active_Widget extends WP_Widget {
 	}
 }
 
-/** Widget AJAX ******************/
-
+/**
+ * AJAX request handler for Members widgets.
+ */
 function bp_core_ajax_widget_members() {
 
 	check_ajax_referer( 'bp_core_widget_members' );
@@ -305,7 +537,16 @@ function bp_core_ajax_widget_members() {
 			break;
 	}
 
-	if ( bp_has_members( 'user_id=0&type=' . $type . '&per_page=' . $_POST['max-members'] . '&max=' . $_POST['max-members'] . '&populate_extras=1' ) ) : ?>
+	$members_args = array(
+		'user_id'         => 0,
+		'type'            => $type,
+		'per_page'        => $_POST['max-members'],
+		'max'             => $_POST['max-members'],
+		'populate_extras' => 1,
+		'search_terms'    => false,
+	);
+
+	if ( bp_has_members( $members_args ) ) : ?>
 		<?php echo '0[[SPLIT]]'; // return valid result. TODO: remove this. ?>
 		<?php while ( bp_members() ) : bp_the_member(); ?>
 			<li class="vcard">
diff --git a/wp-content/plugins/buddypress/bp-core/bp-core-wpabstraction.php b/wp-content/plugins/buddypress/bp-core/bp-core-wpabstraction.php
index c749e6b16c8444b9884a6f24faf7d290cd65643b..18a3c23be5047c3976a712b0b41f9e71f63a727b 100644
--- a/wp-content/plugins/buddypress/bp-core/bp-core-wpabstraction.php
+++ b/wp-content/plugins/buddypress/bp-core/bp-core-wpabstraction.php
@@ -1,22 +1,24 @@
 <?php
-/*****
- * WordPress Abstraction
+/**
+ * WordPress Abstraction.
  *
- * The functions within this file will detect the version of WordPress you are running
- * and will alter the environment so BuddyPress can run regardless.
+ * The functions within this file will detect the version of WordPress you are
+ * running and will alter the environment so BuddyPress can run regardless.
  *
- * The code below mostly contains function mappings. This file is subject to change at any time.
+ * The code below mostly contains function mappings. This file is subject to
+ * change at any time.
  */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Parse the WordPress core version number into the major release
+ * Parse the WordPress core version number into the major release.
  *
  * @since BuddyPress (1.5.2)
+ *
  * @global string $wp_version
- * @return string
+ * @return string $wp_version
  */
 function bp_get_major_wp_version() {
 	global $wp_version;
@@ -34,48 +36,81 @@ if ( !is_multisite() ) {
 	$wpdb->blogid      = BP_ROOT_BLOG;
 
 	if ( !function_exists( 'get_blog_option' ) ) {
+		/**
+		 * @see get_blog_option()
+		 */
 		function get_blog_option( $blog_id, $option_name, $default = false ) {
 			return get_option( $option_name, $default );
 		}
 	}
 
+	if ( ! function_exists( 'add_blog_option' ) ) {
+		/**
+		 * @see add_blog_option()
+		 */
+		function add_blog_option( $blog_id, $option_name, $option_value ) {
+			return add_option( $option_name, $option_value );
+		}
+	}
+
 	if ( !function_exists( 'update_blog_option' ) ) {
+		/**
+		 * @see update_blog_option()
+		 */
 		function update_blog_option( $blog_id, $option_name, $value ) {
 			return update_option( $option_name, $value );
 		}
 	}
 
 	if ( !function_exists( 'delete_blog_option' ) ) {
+		/**
+		 * @see delete_blog_option()
+		 */
 		function delete_blog_option( $blog_id, $option_name ) {
 			return delete_option( $option_name );
 		}
 	}
 
 	if ( !function_exists( 'switch_to_blog' ) ) {
+		/**
+		 * @see switch_to_blog()
+		 */
 		function switch_to_blog() {
 			return bp_get_root_blog_id();
 		}
 	}
 
 	if ( !function_exists( 'restore_current_blog' ) ) {
+		/**
+		 * @see restore_current_blog()
+		 */
 		function restore_current_blog() {
 			return bp_get_root_blog_id();
 		}
 	}
 
 	if ( !function_exists( 'get_blogs_of_user' ) ) {
+		/**
+		 * @see get_blogs_of_user()
+		 */
 		function get_blogs_of_user() {
 			return false;
 		}
 	}
 
 	if ( !function_exists( 'update_blog_status' ) ) {
+		/**
+		 * @see update_blog_status()
+		 */
 		function update_blog_status() {
 			return true;
 		}
 	}
 
 	if ( !function_exists( 'is_subdomain_install' ) ) {
+		/**
+		 * @see is_subdomain_install()
+		 */
 		function is_subdomain_install() {
 			if ( ( defined( 'VHOST' ) && 'yes' == VHOST ) || ( defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) )
 				return true;
@@ -85,6 +120,15 @@ if ( !is_multisite() ) {
 	}
 }
 
+/**
+ * Get SQL chunk for filtering spam users from member queries.
+ *
+ * @internal
+ * @todo Why is this function defined in this file?
+ *
+ * @param string $prefix Global table prefix.
+ * @return string SQL chunk.
+ */
 function bp_core_get_status_sql( $prefix = false ) {
 	if ( !is_multisite() )
 		return "{$prefix}user_status = 0";
@@ -102,10 +146,11 @@ function bp_core_get_status_sql( $prefix = false ) {
  */
 if ( !function_exists( 'mb_strlen' ) ) {
 	/**
-	 * Fallback implementation of mb_strlen, hardcoded to UTF-8.
-	 * @param string $str
-	 * @param string $enc optional encoding; ignored
-	 * @return int
+	 * Fallback implementation of mb_strlen(), hardcoded to UTF-8.
+	 *
+	 * @param string $str String to be measured.
+	 * @param string $enc Optional. Encoding type. Ignored.
+	 * @return int String length.
 	 */
 	function mb_strlen( $str, $enc = '' ) {
 		$counts = count_chars( $str );
@@ -126,12 +171,13 @@ if ( !function_exists( 'mb_strlen' ) ) {
 
 if ( !function_exists( 'mb_strpos' ) ) {
 	/**
-	 * Fallback implementation of mb_strpos, hardcoded to UTF-8.
-	 * @param string $haystack
-	 * @param string $needle
-	 * @param int $offset optional; start position.
-	 * @param string $encoding optional; not used.
-	 * @return int
+	 * Fallback implementation of mb_strpos(), hardcoded to UTF-8.
+	 *
+	 * @param string $haystack String to search in.
+	 * @param string $needle String to search for.
+	 * @param int $offset Optional. Start position for the search. Default: 0.
+	 * @param string $enc Optional. Encoding type. Ignored.
+	 * @return int|bool Position of needle in haystack if found, else false.
 	 */
 	function mb_strpos( $haystack, $needle, $offset = 0, $encoding = '' ) {
 		$needle = preg_quote( $needle, '/' );
@@ -149,12 +195,13 @@ if ( !function_exists( 'mb_strpos' ) ) {
 
 if ( !function_exists( 'mb_strrpos' ) ) {
 	/**
-	 * Fallback implementation of mb_strrpos, hardcoded to UTF-8.
-	 * @param string $haystack
-	 * @param string $needle
-	 * @param int $offset optional; start position.
-	 * @param string $encoding optional; not used.
-	 * @return int
+	 * Fallback implementation of mb_strrpos(), hardcoded to UTF-8.
+	 *
+	 * @param string $haystack String to search in.
+	 * @param string $needle String to search for.
+	 * @param int $offset Optional. Start position for the search. Default: 0.
+	 * @param string $enc Optional. Encoding type. Ignored.
+	 * @return int Position of last needle in haystack if found, else false.
 	 */
 	function mb_strrpos( $haystack, $needle, $offset = 0, $encoding = '' ) {
 		$needle = preg_quote( $needle, '/' );
diff --git a/wp-content/plugins/buddypress/bp-core/css/buddybar.min.css b/wp-content/plugins/buddypress/bp-core/css/buddybar.min.css
index f84d96300292a6f825d1cbda3255afc59256efc7..7208e9be17dc722d80b00644fdb854e3c534333e 100644
--- a/wp-content/plugins/buddypress/bp-core/css/buddybar.min.css
+++ b/wp-content/plugins/buddypress/bp-core/css/buddybar.min.css
@@ -1 +1 @@
-body:not(.wp-admin){padding-top:25px!important}#wp-admin-bar{position:fixed;top:0;left:0;height:25px;font-size:11px;width:100%;z-index:9999}#wp-admin-bar .padder{position:relative;padding:0;width:100%;margin:0 auto;background:url('../images/60pc_black.png');height:25px}body#bp-default #wp-admin-bar .padder{max-width:1250px}#wp-admin-bar *{z-index:999}#wp-admin-bar div#admin-bar-logo{position:absolute;top:5px;left:10px}#wp-admin-bar a img{border:0}#wp-admin-bar li{list-style:none;margin:0;padding:0;line-height:100%;text-align:left}#wp-admin-bar li a{padding:7px 15px 7px 15px;color:#eee;text-decoration:none;font-size:11px}#wp-admin-bar li.alt{border:0}#wp-admin-bar li.no-arrow a{padding-right:15px}#wp-admin-bar ul li ul li a span{display:none}#wp-admin-bar li:hover,#wp-admin-bar li.hover{position:static}#admin-bar-logo{float:left;font-weight:bold;font-size:11px;padding:5px 8px;margin:0;text-decoration:none;color:#fff}body#bp-default #admin-bar-logo{padding:2px 8px}#wp-admin-bar ul{margin:0;list-style:none;line-height:1;cursor:pointer;height:auto;padding:0}#wp-admin-bar ul li{padding:0;float:left;position:relative;background:url('../images/admin-menu-arrow.gif') 88% 53% no-repeat;padding-right:11px}#wp-admin-bar ul li.no-arrow{background:0;padding-right:0}#wp-admin-bar ul li ul li{background-image:none}#wp-admin-bar ul li.align-right{position:absolute;right:0}#wp-admin-bar ul li a{display:block}#wp-admin-bar ul.main-nav li:hover,#wp-admin-bar ul.main-nav li.sfhover,#wp-admin-bar ul.main-nav li ul li.sfhover{background-color:#333}#wp-admin-bar ul li ul{position:absolute;width:185px;left:-999em;margin-left:0;background:#333;border:1px solid #222;-moz-box-shadow:0 4px 8px rgba(0,0,0,0.1);-webkit-box-shadow:0 4px 8px rgba(0,0,0,0.1);-moz-border-radius:3px;-webkit-border-radius:3px;-moz-border-radius-topleft:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-webkit-border-top-right-radius:0}#wp-admin-bar ul li>ul{border-top:0}#wp-admin-bar ul li ul a{color:#eee}#wp-admin-bar ul li ul li{float:left;width:174px;margin:0}#wp-admin-bar ul li ul li:hover a{color:#fff}#wp-admin-bar ul li div.admin-bar-clear{clear:both}#wp-admin-bar ul.main-nav li ul li:hover,#wp-admin-bar ul.main-nav li ul li.sfhover,#wp-admin-bar ul.main-nav li ul li.sfhover{background-color:#222}#wp-admin-bar ul li ul ul{margin:-25px 0 0 184px;-moz-border-radius:3px;-webkit-border-radius:3px}#wp-admin-bar ul li ul li:hover ul li a{color:#eee}#wp-admin-bar ul li ul li ul li:hover a{color:#fff}#wp-admin-bar ul li:hover ul,#wp-admin-bar ul li ul li:hover ul,#wp-admin-bar ul li.sfhover ul,#wp-admin-bar ul li ul li.sfhover ul{left:auto}#wp-admin-bar ul li.align-right:hover ul{right:0}#wp-admin-bar ul li:hover ul ul,#wp-admin-bar li.sfhover ul li ul{left:-999em}#wp-admin-bar img.avatar{float:left;margin-right:8px}#wp-admin-bar span.activity{display:block;margin-left:34px;padding:0}#wp-admin-bar ul.author-list li a{height:17px}#wp-admin-bar ul li#bp-adminbar-notifications-menu a span{padding:0 6px;margin-left:2px;background:#fff;color:#000;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#wp-admin-bar-user-info img.avatar{height:64px;width:64px}
\ No newline at end of file
+body:not(.wp-admin){padding-top:25px !important}#wp-admin-bar{position:fixed;top:0;left:0;height:25px;font-size:11px;width:100%;z-index:9999}#wp-admin-bar .padder{position:relative;padding:0;width:100%;margin:0 auto;background:url('../images/60pc_black.png');height:25px}body#bp-default #wp-admin-bar .padder{max-width:1250px}#wp-admin-bar *{z-index:999}#wp-admin-bar div#admin-bar-logo{position:absolute;top:5px;left:10px}#wp-admin-bar a img{border:0}#wp-admin-bar li{list-style:none;margin:0;padding:0;line-height:100%;text-align:left}#wp-admin-bar li a{padding:7px 15px 7px 15px;color:#eee;text-decoration:none;font-size:11px}#wp-admin-bar li.alt{border:0}#wp-admin-bar li.no-arrow a{padding-right:15px}#wp-admin-bar ul li ul li a span{display:none}#wp-admin-bar li:hover,#wp-admin-bar li.hover{position:static}#admin-bar-logo{float:left;font-weight:bold;font-size:11px;padding:5px 8px;margin:0;text-decoration:none;color:#fff}body#bp-default #admin-bar-logo{padding:2px 8px}#wp-admin-bar ul{margin:0;list-style:none;line-height:1;cursor:pointer;height:auto;padding:0}#wp-admin-bar ul li{padding:0;float:left;position:relative;background:url('../images/admin-menu-arrow.gif') 88% 53% no-repeat;padding-right:11px}#wp-admin-bar ul li.no-arrow{background:0;padding-right:0}#wp-admin-bar ul li ul li{background-image:none}#wp-admin-bar ul li.align-right{position:absolute;right:0}#wp-admin-bar ul li a{display:block}#wp-admin-bar ul.main-nav li:hover,#wp-admin-bar ul.main-nav li.sfhover,#wp-admin-bar ul.main-nav li ul li.sfhover{background-color:#333}#wp-admin-bar ul li ul{position:absolute;width:185px;left:-999em;margin-left:0;background:#333;border:1px solid #222;-moz-box-shadow:0 4px 8px rgba(0,0,0,0.1);-webkit-box-shadow:0 4px 8px rgba(0,0,0,0.1);-moz-border-radius:3px;-webkit-border-radius:3px;-moz-border-radius-topleft:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-webkit-border-top-right-radius:0}#wp-admin-bar ul li>ul{border-top:0}#wp-admin-bar ul li ul a{color:#eee}#wp-admin-bar ul li ul li{float:left;width:174px;margin:0}#wp-admin-bar ul li ul li:hover a{color:#fff}#wp-admin-bar ul li div.admin-bar-clear{clear:both}#wp-admin-bar ul.main-nav li ul li:hover,#wp-admin-bar ul.main-nav li ul li.sfhover,#wp-admin-bar ul.main-nav li ul li.sfhover{background-color:#222}#wp-admin-bar ul li ul ul{margin:-25px 0 0 184px;-moz-border-radius:3px;-webkit-border-radius:3px}#wp-admin-bar ul li ul li:hover ul li a{color:#eee}#wp-admin-bar ul li ul li ul li:hover a{color:#fff}#wp-admin-bar ul li:hover ul,#wp-admin-bar ul li ul li:hover ul,#wp-admin-bar ul li.sfhover ul,#wp-admin-bar ul li ul li.sfhover ul{left:auto}#wp-admin-bar ul li.align-right:hover ul{right:0}#wp-admin-bar ul li:hover ul ul,#wp-admin-bar li.sfhover ul li ul{left:-999em}#wp-admin-bar img.avatar{float:left;margin-right:8px}#wp-admin-bar span.activity{display:block;margin-left:34px;padding:0}#wp-admin-bar ul.author-list li a{height:17px}#wp-admin-bar ul li#bp-adminbar-notifications-menu a span{padding:0 6px;margin-left:2px;background:#fff;color:#000;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#wp-admin-bar-user-info img.avatar{height:64px;width:64px}
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-core/deprecated/1.2.php b/wp-content/plugins/buddypress/bp-core/deprecated/1.2.php
index fc121bfe087836ce256085b55fd830101a641826..e9dc50a2e6ddf8913a84c9aa7bcf6ec74b68257f 100644
--- a/wp-content/plugins/buddypress/bp-core/deprecated/1.2.php
+++ b/wp-content/plugins/buddypress/bp-core/deprecated/1.2.php
@@ -1,4 +1,10 @@
 <?php
+/**
+ * Deprecated Functions
+ *
+ * @package BuddyPress
+ * @subpackage Core
+ */
 
 /**
  * Retrieve sitewide activity
diff --git a/wp-content/plugins/buddypress/bp-core/deprecated/1.5.php b/wp-content/plugins/buddypress/bp-core/deprecated/1.5.php
index 92a43a5f44964613dd81e2478e07b7399e053a2f..b1931b58cb0eb4ce6c889de8b6bdb2e529580793 100644
--- a/wp-content/plugins/buddypress/bp-core/deprecated/1.5.php
+++ b/wp-content/plugins/buddypress/bp-core/deprecated/1.5.php
@@ -139,7 +139,7 @@ function bp_core_get_wp_profile() {
 	$ud = get_userdata( bp_displayed_user_id() ); ?>
 
 <div class="bp-widget wp-profile">
-	<h4><?php _e( 'My Profile' ) ?></h4>
+	<h4><?php _e( 'My Profile', 'buddypress' ) ?></h4>
 
 	<table class="wp-profile-fields">
 
diff --git a/wp-content/plugins/buddypress/bp-core/deprecated/2.0.php b/wp-content/plugins/buddypress/bp-core/deprecated/2.0.php
new file mode 100644
index 0000000000000000000000000000000000000000..18608d2fec92a642404ca197e3726e4dd7e57960
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-core/deprecated/2.0.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Deprecated Functions
+ *
+ * @package BuddyPress
+ * @subpackage Core
+ * @deprecated 2.0.0
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+/**
+ * @deprecated BuddyPress (2.0.0)
+ */
+function bp_activity_clear_meta_cache_for_activity() {
+	_deprecated_function( __FUNCTION__, '2.0.0', 'Use WP metadata API instead' );
+}
+
+/**
+ * @deprecated BuddyPress (2.0.0)
+ */
+function bp_blogs_catch_published_post() {
+	_deprecated_function( __FUNCTION__, '2.0', 'bp_blogs_catch_transition_post_status()' );
+}
+
+/**
+ * @deprecated BuddyPress (2.0.0)
+ */
+function bp_messages_screen_inbox_mark_notifications() {
+	_deprecated_function( __FUNCTION__, '2.0', 'bp_messages_screen_conversation_mark_notifications()' );
+}
diff --git a/wp-content/plugins/buddypress/bp-core/images/bp20/admin-xprofile.jpg b/wp-content/plugins/buddypress/bp-core/images/bp20/admin-xprofile.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..df08e6dc2b9e0a6b4fab412a47fd9d48f817d510
Binary files /dev/null and b/wp-content/plugins/buddypress/bp-core/images/bp20/admin-xprofile.jpg differ
diff --git a/wp-content/plugins/buddypress/bp-core/images/bp20/load-newest.jpg b/wp-content/plugins/buddypress/bp-core/images/bp20/load-newest.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..aba1940eea2b22c95e361aac5a93579e9faf1aba
Binary files /dev/null and b/wp-content/plugins/buddypress/bp-core/images/bp20/load-newest.jpg differ
diff --git a/wp-content/plugins/buddypress/bp-core/images/bp20/performance.png b/wp-content/plugins/buddypress/bp-core/images/bp20/performance.png
new file mode 100644
index 0000000000000000000000000000000000000000..85effa79b22313fe08a2f60c0f061201e1cfef1d
Binary files /dev/null and b/wp-content/plugins/buddypress/bp-core/images/bp20/performance.png differ
diff --git a/wp-content/plugins/buddypress/bp-core/images/bp20/tools-buddypress.jpg b/wp-content/plugins/buddypress/bp-core/images/bp20/tools-buddypress.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7953d9aba26cd7c5c7a62cce9e10dc053491db45
Binary files /dev/null and b/wp-content/plugins/buddypress/bp-core/images/bp20/tools-buddypress.jpg differ
diff --git a/wp-content/plugins/buddypress/bp-core/images/bp20/user-mark-spam.jpg b/wp-content/plugins/buddypress/bp-core/images/bp20/user-mark-spam.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b16e1e3bf56042ffa3e761c749772940e5b6d6c9
Binary files /dev/null and b/wp-content/plugins/buddypress/bp-core/images/bp20/user-mark-spam.jpg differ
diff --git a/wp-content/plugins/buddypress/bp-core/images/bp20/users-pending.jpg b/wp-content/plugins/buddypress/bp-core/images/bp20/users-pending.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4a960b7848136b079503a6021a8c0167139732c8
Binary files /dev/null and b/wp-content/plugins/buddypress/bp-core/images/bp20/users-pending.jpg differ
diff --git a/wp-content/plugins/buddypress/bp-core/js/confirm.js b/wp-content/plugins/buddypress/bp-core/js/confirm.js
new file mode 100644
index 0000000000000000000000000000000000000000..930b146bf931a41c75250a942dd901c1dfa6591d
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-core/js/confirm.js
@@ -0,0 +1,7 @@
+jQuery( document ).ready( function() {
+	jQuery( 'a.confirm').click( function() {
+		if ( confirm( BP_Confirm.are_you_sure ) )
+			return true; else return false;
+	});
+});
+
diff --git a/wp-content/plugins/buddypress/bp-core/js/confirm.min.js b/wp-content/plugins/buddypress/bp-core/js/confirm.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..d8327db1e7fa40aeb43ab0285a6d094ed2bb89cb
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-core/js/confirm.min.js
@@ -0,0 +1 @@
+jQuery(document).ready(function(){jQuery("a.confirm").click(function(){if(confirm(BP_Confirm.are_you_sure)){return true}else{return false}})});
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-forums/bp-forums-actions.php b/wp-content/plugins/buddypress/bp-forums/bp-forums-actions.php
index 9d3161346fcfb412bba8662557715c2657bc8a3f..57e76247d561582ba0f7b4d141073cd5b12542bf 100644
--- a/wp-content/plugins/buddypress/bp-forums/bp-forums-actions.php
+++ b/wp-content/plugins/buddypress/bp-forums/bp-forums-actions.php
@@ -1,3 +1,10 @@
 <?php
+/**
+ * BuddyPress Forums Actions.
+ *
+ * @package BuddyPress
+ * @subpackage Forums
+ */
+
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
diff --git a/wp-content/plugins/buddypress/bp-forums/bp-forums-bbpress-sa.php b/wp-content/plugins/buddypress/bp-forums/bp-forums-bbpress-sa.php
index 42e3ae62ff0be9a681b2683c4dcee749480eaa88..817b24812f328597caa41d4e51eff0ee1128be84 100644
--- a/wp-content/plugins/buddypress/bp-forums/bp-forums-bbpress-sa.php
+++ b/wp-content/plugins/buddypress/bp-forums/bp-forums-bbpress-sa.php
@@ -1,12 +1,24 @@
 <?php
+/**
+ * BuddyPress bbPress 1.x integration.
+ *
+ * @package BuddyPress
+ * @subpackage Forums
+ */
+
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Bootstrap bbPress 1.x, and manipulate globals to integrate with BuddyPress.
+ *
+ * @return bool|null Returns false on failure.
+ */
 function bp_forums_load_bbpress() {
-	global $bp, $wpdb, $wp_roles, $current_user, $wp_users_object;
+	global $wpdb, $wp_roles, $current_user, $wp_users_object;
 	global $bb, $bbdb, $bb_table_prefix, $bb_current_user;
 	global $bb_roles, $wp_taxonomy_object, $bb_queries;
-
+	
 	// Return if we've already run this function.
 	if ( is_object( $bbdb ) )
 		return;
@@ -14,9 +26,11 @@ function bp_forums_load_bbpress() {
 	if ( !bp_forums_is_installed_correctly() )
 		return false;
 
-	define( 'BB_PATH', BP_PLUGIN_DIR . '/bp-forums/bbpress/' );
-	define( 'BACKPRESS_PATH', BP_PLUGIN_DIR . '/bp-forums/bbpress/bb-includes/backpress/' );
-	define( 'BB_URL', BP_PLUGIN_URL . 'bp-forums/bbpress/' );
+	$bp = buddypress();
+
+	define( 'BB_PATH',        $bp->plugin_dir . '/bp-forums/bbpress/' );
+	define( 'BACKPRESS_PATH', $bp->plugin_dir . '/bp-forums/bbpress/bb-includes/backpress/' );
+	define( 'BB_URL',         $bp->plugin_url . 'bp-forums/bbpress/' );
 	define( 'BB_INC', 'bb-includes/' );
 
 	require( BB_PATH . BB_INC . 'class.bb-query.php' );
@@ -114,9 +128,30 @@ function bp_forums_load_bbpress() {
 }
 add_action( 'bbpress_init', 'bp_forums_load_bbpress' );
 
-/* WP to bbP wrapper functions */
+/** WP to bbPress wrapper functions ******************************************/
+
+/**
+ * Get the current bbPress user.
+ *
+ * @return object $current_user Current user object from WordPress.
+ */
 function bb_get_current_user() { global $current_user; return $current_user; }
+
+/**
+ * Get userdata for a bbPress user.
+ *
+ * @param int $user_id User ID.
+ * @return object User data from WordPress.
+ */
 function bb_get_user( $user_id ) { return get_userdata( $user_id ); }
+
+/**
+ * Cache users.
+ *
+ * Noop.
+ *
+ * @param array $users
+ */
 function bb_cache_users( $users ) {}
 
 /**
@@ -133,8 +168,7 @@ class BP_Forums_BB_Auth {
 }
 
 /**
- * bbPress needs the DB class to be BPDB, but we want to use WPDB, so we can
- * extend it and use this.
+ * bbPress needs the DB class to be BPDB, but we want to use WPDB, so we can extend it and use this.
  *
  * The class is pluggable, so that plugins that swap out WPDB with a custom
  * database class (such as HyperDB and SharDB) can provide their own versions
@@ -144,6 +178,11 @@ if ( ! class_exists( 'BPDB' ) ) :
 	class BPDB extends WPDB {
 		var $db_servers = array();
 
+		/**
+		 * Constructor
+		 *
+		 * @see WPDB::__construct() for description of parameters.
+		 */
 		function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
 			parent::__construct( $dbuser, $dbpassword, $dbname, $dbhost );
 
@@ -157,9 +196,19 @@ if ( ! class_exists( 'BPDB' ) ) :
 		/**
 		 * Determine if a database supports a particular feature.
 		 *
-		 * Overriden here to work around differences between bbPress', and WordPress', implementation differences.
-		 * In particular, when BuddyPress tries to run bbPress' SQL installation script, the collation check always
-		 * failed. The capability is long supported by WordPress' minimum required MySQL version, so this is safe.
+		 * Overriden here to work around differences between bbPress's
+		 * and WordPress's implementations. In particular, when
+		 * BuddyPress tries to run bbPress' SQL installation script,
+		 * the collation check always failed. The capability is long
+		 * supported by WordPress' minimum required MySQL version, so
+		 * this is safe.
+		 *
+		 * @see WPDB::has_cap() for a description of parameters and
+		 *      return values.
+		 *
+		 * @param string $db_cap See {@link WPDB::has_cap()}.
+		 * @param string $_table_name See {@link WPDB::has_cap()}.
+		 * @return bool See {@link WPDB::has_cap()}.
 		 */
 		function has_cap( $db_cap, $_table_name='' ) {
 			if ( 'collation' == $db_cap )
@@ -169,8 +218,12 @@ if ( ! class_exists( 'BPDB' ) ) :
 		}
 
 		/**
-		 * Initialises the class variables based on provided arguments.
-		 * Based on, and taken from, the BackPress class in turn taken from the 1.0 branch of bbPress.
+		 * Initialize the class variables based on provided arguments.
+		 *
+		 * Based on, and taken from, the BackPress class in turn taken
+		 * from the 1.0 branch of bbPress.
+		 *
+		 * @see BBDB::__construct() for a description of params.
 		 */
 		function init( $args ) {
 			if ( 4 == func_num_args() ) {
@@ -197,13 +250,29 @@ if ( ! class_exists( 'BPDB' ) ) :
 			return wp_parse_args( $args, $defaults );
 		}
 
+		/**
+		 * Stub for escape_deep() compatibility.
+		 *
+		 * @see WPDB::escape_deep() for description of parameters and
+		 *      return values.
+		 *
+		 * @param mixed $data See {@link WPDB::escape_deep()}.
+		 * @return mixed $data See {@link WPDB::escape_deep()}.
+		 */
 		function escape_deep( $data ) {
 			return $this->escape( $data );
 		}
 	}
 endif; // class_exists( 'BPDB' )
 
-/* BBPress needs this function to convert vars */
+/**
+ * Convert object to given output format.
+ *
+ * bbPress needs this to convert vars.
+ *
+ * @param object $object Object to convert.
+ * @param string $output Type of object to return. OBJECT, ARRAY_A, or ARRAY_N.
+ */
 function backpress_convert_object( &$object, $output ) {
 	if ( is_array( $object ) ) {
 		foreach ( array_keys( $object ) as $key )
@@ -218,12 +287,16 @@ function backpress_convert_object( &$object, $output ) {
 }
 
 /**
+ * Parse and execute queries for updating a set of database tables.
+ *
  * Copied from wp-admin/includes/upgrade.php, this will take care of creating
  * the bbPress stand-alone tables without loading a conflicting WP Admin.
  *
- * @param array $queries
- * @param bool $execute Optional; defaults to true.
- * @return array
+ * @see dbDelta() for a description of parameters and return value.
+ *
+ * @param array $queries See {@link dbDelta()}.
+ * @param bool $execute See {@link dbDelta()}.
+ * @return array See {@link dbDelta()}.
  */
 function bp_bb_dbDelta($queries, $execute = true) {
 	global $wpdb;
diff --git a/wp-content/plugins/buddypress/bp-forums/bp-forums-filters.php b/wp-content/plugins/buddypress/bp-forums/bp-forums-filters.php
index 171bd69477eb2a8be3c43cad59d3b7ae7299afc2..204a95392515104d1a6f7d7c9feb458b8522a088 100644
--- a/wp-content/plugins/buddypress/bp-forums/bp-forums-filters.php
+++ b/wp-content/plugins/buddypress/bp-forums/bp-forums-filters.php
@@ -1,4 +1,11 @@
 <?php
+/**
+ * BuddyPress Forums Filters.
+ *
+ * @package BuddyPress
+ * @subpackage Forums
+ */
+
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
@@ -47,6 +54,12 @@ add_filter( 'bp_get_the_topic_title', 'bp_forums_make_nofollow_filter' );
 add_filter( 'bp_get_the_topic_latest_post_excerpt', 'bp_forums_make_nofollow_filter' );
 add_filter( 'bp_get_the_topic_post_content', 'bp_forums_make_nofollow_filter' );
 
+/**
+ * Custom KSES filter for the Forums component.
+ *
+ * @param string $content Content to sanitize.
+ * @return string Sanitized string.
+ */
 function bp_forums_filter_kses( $content ) {
 	global $allowedtags;
 
@@ -74,6 +87,15 @@ function bp_forums_filter_kses( $content ) {
 	return wp_kses( $content, $forums_allowedtags );
 }
 
+/**
+ * Get a link for a forum topic tags directory.
+ *
+ * @param string $link Link passed from filter.
+ * @param string $tag Name of the tag.
+ * @param string $page Page number, passed from the filter.
+ * @param string $context Passed from the filter but unused here.
+ * @return string Link of the form http://example.com/forums/tag/tagname/.
+ */
 function bp_forums_filter_tag_link( $link, $tag, $page, $context ) {
 	global $bp;
 
@@ -81,9 +103,21 @@ function bp_forums_filter_tag_link( $link, $tag, $page, $context ) {
 }
 add_filter( 'bb_get_tag_link', 'bp_forums_filter_tag_link', 10, 4);
 
+/**
+ * Add rel="nofollow" to bbPress content.
+ *
+ * @param string $text Post content.
+ * @return string Modified post content.
+ */
 function bp_forums_make_nofollow_filter( $text ) {
 	return preg_replace_callback( '|<a (.+?)>|i', 'bp_forums_make_nofollow_filter_callback', $text );
 }
+	/**
+	 * Callback for preg_replace_callback() in bp_forums_make_nofollow_filter().
+	 *
+	 * @param array $matches Regex matches from {@link bp_forums_make_nofollow_filter()}.
+	 * @return string Text with nofollow links.
+	 */
 	function bp_forums_make_nofollow_filter_callback( $matches ) {
 		$text = $matches[1];
 		$text = str_replace( array( ' rel="nofollow"', " rel='nofollow'"), '', $text );
@@ -91,17 +125,17 @@ function bp_forums_make_nofollow_filter( $text ) {
 	}
 
 /**
- * bp_forums_add_forum_topic_to_page_title( $title )
+ * Append forum topic to page title.
  *
- * Append forum topic to page title
+ * @global object $bp Global BuddyPress settings object.
  *
- * @global object $bp
- * @param string $title New page title; see bp_modify_page_title()
- * @param string $title Original page title
- * @param string $sep How to separate the various items within the page title.
- * @param string $seplocation Direction to display title
- * @return string
  * @see bp_modify_page_title()
+ *
+ * @param string $title New page title; see {@link bp_modify_page_title()}.
+ * @param string $original_title Original page title.
+ * @param string $sep How to separate the various items within the page title.
+ * @param string $seplocation Direction to display title.
+ * @return string Page title with forum topic title appended.
  */
 function bp_forums_add_forum_topic_to_page_title( $title, $original_title, $sep, $seplocation  ) {
 	global $bp;
@@ -115,14 +149,14 @@ function bp_forums_add_forum_topic_to_page_title( $title, $original_title, $sep,
 add_filter( 'bp_modify_page_title', 'bp_forums_add_forum_topic_to_page_title', 9, 4 );
 
 /**
- * bp_forums_strip_mentions_on_post_edit( $title )
+ * Remove the anchor tag autogenerated for at-mentions when forum topics and posts are edited.
  *
- * Removes the anchor tag autogenerated for at-mentions when forum topics and posts are edited.
  * Prevents embedded anchor tags.
  *
- * @global object $bp
- * @param string $content
- * @return string $content
+ * @global object $bp Global BuddyPress settings object.
+ *
+ * @param string $content Edited post content.
+ * @return string $content Sanitized post content.
  */
 function bp_forums_strip_mentions_on_post_edit( $content ) {
 	global $bp;
@@ -138,20 +172,17 @@ function bp_forums_strip_mentions_on_post_edit( $content ) {
 add_filter( 'bp_get_the_topic_post_edit_text', 'bp_forums_strip_mentions_on_post_edit' );
 add_filter( 'bp_get_the_topic_text', 'bp_forums_strip_mentions_on_post_edit' );
 
-/**
- * "REPLIED TO" SQL FILTERS
- */
+/** "Replied to" SQL filters *************************************************/
 
 /**
- * Filters the get_topics_distinct portion of the Forums sql when on a user's Replied To page.
+ * Filter the get_topics_distinct portion of the Forums SQL when on a user's Replied To page.
  *
- * This filter is added in bp_has_forum_topics()
+ * This filter is added in bp_has_forum_topics().
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param string $sql
- * @return string $sql
+ * @param string $sql SQL fragment.
+ * @return string $sql SQL fragment of the form "DISTINCT t.topic_id, ".
  */
 function bp_forums_add_replied_distinct_sql( $sql ) {
 	$sql = "DISTINCT t.topic_id, ";
@@ -160,17 +191,16 @@ function bp_forums_add_replied_distinct_sql( $sql ) {
 }
 
 /**
- * Filters the get_topics_join portion of the Forums sql when on a user's Replied To page.
+ * Filter the get_topics_join portion of the Forums sql when on a user's Replied To page.
  *
- * This filter is added in bp_has_forum_topics()
+ * This filter is added in bp_has_forum_topics().
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @global object $bbdb The bbPress database global
- * @global object $wpdb The WordPress database global
- * @param string $sql
- * @return string $sql
+ * @global object $bbdb The bbPress database global.
+ *
+ * @param string $sql SQL statement.
+ * @return string $sql SQL statement.
  */
 function bp_forums_add_replied_join_sql( $sql ) {
 	global $bbdb;
@@ -181,16 +211,16 @@ function bp_forums_add_replied_join_sql( $sql ) {
 }
 
 /**
- * Filters the get_topics_where portion of the Forums sql when on a user's Replied To page.
+ * Filter the get_topics_where portion of the Forums sql when on a user's Replied To page.
  *
- * This filter is added in bp_has_forum_topics()
+ * This filter is added in bp_has_forum_topics().
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @global object $wpdb The WordPress database global.
  *
- * @global object $wpdb The WordPress database global
- * @param string $sql
- * @return string $sql
+ * @param string $sql SQL fragment.
+ * @return string $sql SQL fragment.
  */
 function bp_forums_add_replied_where_sql( $sql ) {
 	global $wpdb;
diff --git a/wp-content/plugins/buddypress/bp-forums/bp-forums-functions.php b/wp-content/plugins/buddypress/bp-forums/bp-forums-functions.php
index cb31691cca10ed3d2bcfe9bcf2f5fa31ff6020ec..796eadc0265a04aaf07b573f18de8622bf3c3acb 100644
--- a/wp-content/plugins/buddypress/bp-forums/bp-forums-functions.php
+++ b/wp-content/plugins/buddypress/bp-forums/bp-forums-functions.php
@@ -1,4 +1,10 @@
 <?php
+/**
+ * BuddyPress Forums Functions.
+ *
+ * @package BuddyPress
+ * @subpackage Forums
+ */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
@@ -6,10 +12,11 @@ if ( !defined( 'ABSPATH' ) ) exit;
 /** bbPress 2.x ***************************************************************/
 
 /**
- * Used to see if bbPress 2.x is installed and active
+ * Is see bbPress 2.x is installed and active?
  *
- * @since BuddyPress (1.6)
- * @return boolean True if bbPress 2.x is active, false if not
+ * @since BuddyPress (1.6.0)
+ *
+ * @return boolean True if bbPress 2.x is active, false if not.
  */
 function bp_forums_is_bbpress_active() {
 
@@ -28,10 +35,14 @@ function bp_forums_is_bbpress_active() {
 /** bbPress 1.x ***************************************************************/
 
 /**
- * If the bb-config-location option exists, bbPress 1.x was previously installed
+ * See if bbPress 1.x is installed correctly.
+ *
+ * "Installed correctly" means that the bb-config-location option is set, and
+ * the referenced file exists.
+ *
+ * @since BuddyPress (1.2.0)
  *
- * @since BuddyPress (1.2)
- * @return boolean True if option exists, false if not
+ * @return boolean True if option exists, false if not.
  */
 function bp_forums_is_installed_correctly() {
 	$bp = buddypress();
@@ -43,12 +54,15 @@ function bp_forums_is_installed_correctly() {
 }
 
 /**
+ * Does the forums component have a directory page registered?
+ *
  * Checks $bp pages global and looks for directory page
  *
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
+ *
+ * @global BuddyPress $bp The one true BuddyPress instance.
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @return bool True if set, False if empty
+ * @return bool True if set, False if empty.
  */
 function bp_forums_has_directory() {
 	return (bool) !empty( buddypress()->pages->forums->id );
@@ -56,11 +70,35 @@ function bp_forums_has_directory() {
 
 /** Forum Functions ***********************************************************/
 
+/**
+ * Get a forum by ID.
+ *
+ * Wrapper for {@link bb_get_forum()}.
+ *
+ * @param int $forum_id ID of the forum being fetched.
+ * @return object bbPress forum object.
+ */
 function bp_forums_get_forum( $forum_id ) {
 	do_action( 'bbpress_init' );
 	return bb_get_forum( $forum_id );
 }
 
+/**
+ * Create a forum.
+ *
+ * Wrapper for {@link bb_new_forum()}.
+ *
+ * @param array $args {
+ *     Forum setup arguments.
+ *     @type string $forum_name Name of the forum.
+ *     @type string $forum_desc Description of the forum.
+ *     @type int $forum_parent_id ID of the forum parent. Default: value of
+ *           {@link bp_forums_parent_forums_id()}.
+ *     @type bool $forum_order Order.
+ *     @type int $forum_is_category Whether the forum is a category. Default: 0.
+ * }
+ * @return int ID of the newly created forum.
+ */
 function bp_forums_new_forum( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -76,6 +114,23 @@ function bp_forums_new_forum( $args = '' ) {
 	return bb_new_forum( array( 'forum_name' => stripslashes( $forum_name ), 'forum_desc' => stripslashes( $forum_desc ), 'forum_parent' => $forum_parent_id, 'forum_order' => $forum_order, 'forum_is_category' => $forum_is_category ) );
 }
 
+/**
+ * Update a forum.
+ *
+ * Wrapper for {@link bb_update_forum(}.
+ *
+ * @param array $args {
+ *     Forum setup arguments.
+ *     @type int $forum_id ID of the forum to be updated.
+ *     @type string $forum_name Name of the forum.
+ *     @type string $forum_desc Description of the forum.
+ *     @type int $forum_parent_id ID of the forum parent. Default: value of
+ *           {@link bp_forums_parent_forums_id()}.
+ *     @type bool $forum_order Order.
+ *     @type int $forum_is_category Whether the forum is a category. Default: 0.
+ * }
+ * @return bool Ttrue on success, false on failure.
+ */
 function bp_forums_update_forum( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -93,6 +148,11 @@ function bp_forums_update_forum( $args = '' ) {
 	return bb_update_forum( array( 'forum_id' => (int) $forum_id, 'forum_name' => stripslashes( $forum_name ), 'forum_desc' => stripslashes( $forum_desc ), 'forum_slug' => stripslashes( $forum_slug ), 'forum_parent' => $forum_parent_id, 'forum_order' => $forum_order, 'forum_is_category' => $forum_is_category ) );
 }
 
+/**
+ * Delete a group forum by the group id.
+ *
+ * @param int $group_id ID of the group whose forum is to be deleted.
+ */
 function bp_forums_delete_group_forum( $group_id ) {
 	$forum_id = groups_get_groupmeta( $group_id, 'forum_id' );
 
@@ -105,6 +165,28 @@ add_action( 'groups_delete_group', 'bp_forums_delete_group_forum' );
 
 /** Topic Functions ***********************************************************/
 
+/**
+ * Fetch a set of forum topics.
+ *
+ * @param array $args {
+ *     @type string @type Order or filter type. Default: 'newest'.
+ *     @type int $forum_id Optional. Pass a forum ID to limit results to topics
+ *           associated with that forum.
+ *     @type int $user_id Optional. Pass a user ID to limit results to topics
+ *           belonging to that user.
+ *     @type int $page Optional. Number of the results page to return.
+ *           Default: 1.
+ *     @type int $per_page Optional. Number of results to return per page.
+ *           Default: 15.
+ *     @type int $offset Optional. Numeric offset for results.
+ *     @type int $number
+ *     @type array $exclude Optional. Topic IDs to exclude.
+ *     @type string $show_stickies Whether to show sticky topics.
+ *     @type mixed $filter If $type = 'tag', filter is the tag name. Otherwise,
+ *           $filter is terms to search on.
+ * }
+ * @return array Found topics.
+ */
 function bp_forums_get_forum_topics( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -151,6 +233,12 @@ function bp_forums_get_forum_topics( $args = '' ) {
 	return apply_filters_ref_array( 'bp_forums_get_forum_topics', array( &$topics, &$r ) );
 }
 
+/**
+ * Get additional details about a given forum topic.
+ *
+ * @param int $topic_id ID of the topic for which you're fetching details.
+ * @return object Details about the topic.
+ */
 function bp_forums_get_topic_details( $topic_id ) {
 	do_action( 'bbpress_init' );
 
@@ -159,6 +247,14 @@ function bp_forums_get_topic_details( $topic_id ) {
 	return $query->results[0];
 }
 
+/**
+ * Get the numeric ID of a topic from the topic slug.
+ *
+ * Wrapper for {@link bb_get_id_from_slug()}.
+ *
+ * @param string $topic_slug Slug of the topic.
+ * @return int|bool ID of the topic (if found), false on failure.
+ */
 function bp_forums_get_topic_id_from_slug( $topic_slug ) {
 	do_action( 'bbpress_init' );
 
@@ -168,6 +264,34 @@ function bp_forums_get_topic_id_from_slug( $topic_slug ) {
 	return bb_get_id_from_slug( 'topic', $topic_slug );
 }
 
+/**
+ * Create a new forum topic.
+ *
+ * @param array $args {
+ *     @type string $topic_title Title of the new topic.
+ *     @type string $topic_slug Slug of the new topic.
+ *     @type string $topic_text Text of the new topic.
+ *     @type int $topic_poster ID of the user posting the topic. Default: ID of
+ *           the logged-in user.
+ *     @type string $topic_poster_name Display name of the user posting the
+ *           topic. Default: 'fullname' of the logged-in user.
+ *     @type id $topic_last_poster ID of the user who last posted to the topic.
+ *           Default: ID of the logged-in user.
+ *     @type string $topic_last_poster_name Display name of the user who last
+ *           posted to the topic. Default: 'fullname' of the logged-in user.
+ *     @type string $topic_start_time Date/time when the topic was created.
+ *           Default: the current time, as reported by bp_core_current_time().
+ *     @type string $topic_time Date/time when the topic was created.
+ *           Default: the current time, as reported by bp_core_current_time().
+ *     @type int $topic_open Whether the topic is open. Default: 1 (open).
+ *     @type array|string|bool $topic_tags Array or comma-separated list of
+ *           topic tags. False to leave empty. Default: false.
+ *     @type int $forum_id ID of the forum to which the topic belongs.
+ *           Default: 0.
+ * }
+ * @return object Details about the new topic, as returned by
+ *         {@link bp_forums_get_topic_details()}.
+ */
 function bp_forums_new_topic( $args = '' ) {
 	global $bp;
 
@@ -215,6 +339,20 @@ function bp_forums_new_topic( $args = '' ) {
 	return $topic_id;
 }
 
+/**
+ * Update a topic's details.
+ *
+ * @param array $args {
+ *     Array of arguments.
+ *     @type int $topic_id ID of the topic being updated.
+ *     @type string $topic_title Updated title of the topic.
+ *     @type string $topic_title Updated text of the topic.
+ *     @type array|string|bool $topic_tags Array or comma-separated list of
+ *           topic tags. False to leave empty. Default: false.
+ * }
+ * @return object Details about the new topic, as returned by
+ *         {@link bp_forums_get_topic_details()}.
+ */
 function bp_forums_update_topic( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -263,6 +401,16 @@ function bp_forums_sticky_topic( $args = '' ) {
 	return false;
 }
 
+/**
+ * Set a topic's open/closed status.
+ *
+ * @param array $args {
+ *     @type int $topic_id ID of the topic whose status is being changed.
+ *     @type string $mode New status of the topic. 'open' or 'close'.
+ *           Default: 'close'.
+ * }
+ * @return bool True on success, false on failure.
+ */
 function bp_forums_openclose_topic( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -280,6 +428,14 @@ function bp_forums_openclose_topic( $args = '' ) {
 	return false;
 }
 
+/**
+ * Delete a topic.
+ *
+ * @param array $args {
+ *     @type int $topic_id ID of the topic being deleted.
+ * }
+ * @return bool True on success, false on failure.
+ */
 function bp_forums_delete_topic( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -291,6 +447,11 @@ function bp_forums_delete_topic( $args = '' ) {
 	return bb_delete_topic( $topic_id, 1 );
 }
 
+/**
+ * Get a count of the total topics on the site.
+ *
+ * @return int $count Total topic count.
+ */
 function bp_forums_total_topic_count() {
 	global $bbdb;
 
@@ -315,13 +476,15 @@ function bp_forums_total_topic_count() {
 
 /**
  * Check to see whether a user has already left this particular reply on a given post.
- * Prevents dupes.
  *
- * @since BuddyPress (1.6)
+ * Used to prevent dupes.
+ *
+ * @since BuddyPress (1.6.0)
  *
- * @param string $text The text of the comment
- * @param int $topic_id The topic id
- * @param int $user_id The user id
+ * @param string $text The text of the comment.
+ * @param int $topic_id The topic id.
+ * @param int $user_id The user id.
+ * @return bool True if a duplicate reply exists, otherwise false.
  */
 function bp_forums_reply_exists( $text = '', $topic_id = 0, $user_id = 0 ) {
 
@@ -354,24 +517,26 @@ function bp_forums_reply_exists( $text = '', $topic_id = 0, $user_id = 0 ) {
 	/**
 	 * Private one-time-use function used in conjunction with bp_forums_reply_exists()
 	 *
-	 * @since BuddyPress (1.7)
 	 * @access private
-	 * @global WPDB $wpdb
-	 * @param string $where
-	 * @return string
+	 * @since BuddyPress (1.7.0)
+	 *
+	 * @global WPDB $wpdb WordPress database access object.
+	 *
+	 * @param string $where SQL fragment.
+	 * @return string SQL fragment.
 	 */
 	function _bp_forums_reply_exists_posts_where( $where = '' ) {
 		return $where . " AND p.post_text = '" . buddypress()->forums->reply_exists_text . "'";
 	}
 
 /**
- * Get a total "Topics Started" count for a given user
- *
- * @package BuddyPress
+ * Get a total "Topics Started" count for a given user.
  *
- * @param int $user_id ID of the user being queried. Falls back on displayed user, then loggedin
- * @param string $type The current filter/sort type. 'active', 'popular', 'unreplied'
- * @return int $count The topic count
+ * @param int $user_id ID of the user being queried. Falls back on displayed
+ *        user, then loggedin.
+ * @param string $type The current filter/sort type. 'active', 'popular',
+ *        'unreplied'.
+ * @return int $count The topic count.
  */
 function bp_forums_total_topic_count_for_user( $user_id = 0, $type = 'active' ) {
 	do_action( 'bbpress_init' );
@@ -401,15 +566,16 @@ function bp_forums_total_topic_count_for_user( $user_id = 0, $type = 'active' )
 }
 
 /**
- * Return the total number of topics replied to by a given user
+ * Return the total number of topics replied to by a given user.
  *
- * Uses an unfortunate technique to count unique topics, due to limitations in BB_Query.
+ * Uses an unfortunate technique to count unique topics, due to limitations in
+ * BB_Query.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @param int $user_id Defaults to displayed user, then to logged-in user
- * @return int $count
+ * @param int $user_id ID of the user whose replied topics are being counted.
+ *        Defaults to displayed user, then to logged-in user.
+ * @return int $count Topic count.
  */
 function bp_forums_total_replied_count_for_user( $user_id = 0, $type = 'active' ) {
 	do_action( 'bbpress_init' );
@@ -446,6 +612,17 @@ function bp_forums_total_replied_count_for_user( $user_id = 0, $type = 'active'
 	return apply_filters( 'bp_forums_total_replied_count_for_user', $count, $user_id );
 }
 
+/**
+ * Fetch BP-specific details for an array of topics.
+ *
+ * Done in one fell swoop to reduce query overhead. Currently determines the
+ * following:
+ * - details about the last poster
+ * - information about topic users that may have been deleted/spammed
+ *
+ * @param array $topics Array of topics.
+ * @return array $topics Topics with BP details added.
+ */
 function bp_forums_get_topic_extras( $topics ) {
 	global $wpdb, $bbdb;
 
@@ -503,6 +680,18 @@ function bp_forums_get_topic_extras( $topics ) {
 
 /** Post Functions ************************************************************/
 
+/**
+ * Get the posts belonging to a topic.
+ *
+ * @param array $args {
+ *     @type int $topic_id ID of the topic for which posts are being fetched.
+ *     @type int $page Optional. Page of results to return. Default: 1.
+ *     @type int $page Optional. Number of results to return per page.
+ *           Default: 15.
+ *     @type string $order 'ASC' or 'DESC'. Default: 'ASC'.
+ * }
+ * @return array List of posts.
+ */
 function bp_forums_get_topic_posts( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -519,11 +708,29 @@ function bp_forums_get_topic_posts( $args = '' ) {
 	return bp_forums_get_post_extras( $query->results );
 }
 
+/**
+ * Get a single post object by ID.
+ *
+ * Wrapper for {@link bb_get_post()}.
+ *
+ * @param int $post_id ID of the post being fetched.
+ * @return object Post object.
+ */
 function bp_forums_get_post( $post_id ) {
 	do_action( 'bbpress_init' );
 	return bb_get_post( $post_id );
 }
 
+/**
+ * Delete a post.
+ *
+ * Wrapper for {@link bb_delete_post()}.
+ *
+ * @param array $args {
+ *     @type int $post_id ID of the post being deleted.
+ * }
+ * @return bool True on success, false on failure.
+ */
 function bp_forums_delete_post( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -536,6 +743,25 @@ function bp_forums_delete_post( $args = '' ) {
 	return bb_delete_post( $post_id, 1 );
 }
 
+/**
+ * Create a new post.
+ *
+ * @param array $args {
+ *     @type int $post_id Optional. ID of an existing post, if you want to
+ *           update rather than create. Default: false.
+ *     @type int $topic_id ID of the topic to which the post belongs.
+ *     @type string $post_text Contents of the post.
+ *     @type string $post_time Optional. Time when the post was recorded.
+ *           Default: current time, as reported by {@link bp_core_current_time()}.
+ *     @type int $poster_id Optional. ID of the user creating the post.
+ *           Default: ID of the logged-in user.
+ *     @type string $poster_ip Optional. IP address of the user creating the
+ *           post. Default: the IP address found in $_SERVER['REMOTE_ADDR'].
+ *     @type int $post_status Post status. Default: 0.
+ *     @type int $post_position Optional. Default: false (auto).
+ * }
+ * @return int|bool ID of the new post on success, false on failure.
+ */
 function bp_forums_insert_post( $args = '' ) {
 	do_action( 'bbpress_init' );
 
@@ -582,6 +808,16 @@ function bp_forums_insert_post( $args = '' ) {
 	return $post_id;
 }
 
+/**
+ * Get BP-specific details about a set of posts.
+ *
+ * Currently fetches the following:
+ * - WP userdata for each poster
+ * - BP fullname for each poster
+ *
+ * @param array $posts List of posts.
+ * @return array Posts with BP-data added.
+ */
 function bp_forums_get_post_extras( $posts ) {
 	global $bp, $wpdb;
 
@@ -620,6 +856,13 @@ function bp_forums_get_post_extras( $posts ) {
 	return apply_filters( 'bp_forums_get_post_extras', $posts );
 }
 
+/**
+ * Get topic and post counts for a given forum.
+ *
+ * @param int $forum_id ID of the forum.
+ * @return object Object with properties $topics (topic count) and $posts
+ *         (post count).
+ */
 function bp_forums_get_forum_topicpost_count( $forum_id ) {
 	global $wpdb, $bbdb;
 
@@ -629,6 +872,12 @@ function bp_forums_get_forum_topicpost_count( $forum_id ) {
 	return $wpdb->get_results( $wpdb->prepare( "SELECT topics, posts from {$bbdb->forums} WHERE forum_id = %d", $forum_id ) );
 }
 
+/**
+ * Map WordPress caps onto bbPress users, to ensure that they can post.
+ *
+ * @param array $allcaps Array of capabilities.
+ * @return array Caps array with bbPress caps added.
+ */
 function bp_forums_filter_caps( $allcaps ) {
 	global $wp_roles, $bb_table_prefix;
 
@@ -649,12 +898,11 @@ function bp_forums_filter_caps( $allcaps ) {
 add_filter( 'user_has_cap', 'bp_forums_filter_caps' );
 
 /**
- * Returns the parent forum id for the bbPress abstraction layer
+ * Return the parent forum ID for the bbPress abstraction layer.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return int
+ * @return int Forum ID.
  */
 function bp_forums_parent_forum_id() {
 	return apply_filters( 'bp_forums_parent_forum_id', BP_FORUMS_PARENT_FORUM_ID );
@@ -663,23 +911,22 @@ function bp_forums_parent_forum_id() {
 /**
  * Should sticky topics be broken out of regular topic order on forum directories?
  *
- * Defaults to false. Define BP_FORUMS_ENABLE_GLOBAL_DIRECTORY_STICKIES, or filter
- * bp_forums_enable_global_directory_stickies, to change this behavior.
+ * Defaults to false. Define BP_FORUMS_ENABLE_GLOBAL_DIRECTORY_STICKIES, or
+ * filter 'bp_forums_enable_global_directory_stickies', to change this behavior.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return bool True if stickies should be displayed at the top of the global directory, false
- *    otherwise.
+ * @return bool True if stickies should be displayed at the top of the global
+ *         directory, otherwise false.
  */
 function bp_forums_enable_global_directory_stickies() {
 	return apply_filters( 'bp_forums_enable_global_directory_stickies', defined( 'BP_FORUMS_ENABLE_GLOBAL_DIRECTORY_STICKIES' ) && BP_FORUMS_ENABLE_GLOBAL_DIRECTORY_STICKIES );
 }
 
 
-/********************************************************************************
- * Caching
- *
+/** Caching ******************************************************************/
+
+/**
  * Caching functions handle the clearing of cached objects and pages on specific
  * actions throughout BuddyPress.
  */
@@ -693,14 +940,16 @@ add_action( 'bp_forums_new_post',  'bp_core_clear_cache' );
 /** Embeds *******************************************************************/
 
 /**
+ * Attempt to retrieve the oEmbed cache for a forum topic.
+ *
  * Grabs the topic post ID and attempts to retrieve the oEmbed cache (if it exists)
  * during the forum topic loop.  If no cache and link is embeddable, cache it.
  *
+ * @since BuddyPress (1.5.0)
+ *
  * @see BP_Embed
  * @see bp_embed_forum_cache()
  * @see bp_embed_forum_save_cache()
- * @package BuddyPress_Forums
- * @since BuddyPress (1.5)
  */
 function bp_forums_embed() {
 	add_filter( 'embed_post_id',         'bp_get_the_topic_post_id'         );
@@ -710,9 +959,10 @@ function bp_forums_embed() {
 add_action( 'topic_loop_start', 'bp_forums_embed' );
 
 /**
- * Wrapper function for {@link bb_get_postmeta()}.
  * Used during {@link BP_Embed::parse_oembed()} via {@link bp_forums_embed()}.
  *
+ * Wrapper function for {@link bb_get_postmeta()}.
+ *
  * @package BuddyPress_Forums
  * @since BuddyPress (1.5)
  */
@@ -721,11 +971,11 @@ function bp_embed_forum_cache( $cache, $id, $cachekey ) {
 }
 
 /**
- * Wrapper function for {@link bb_update_postmeta()}.
  * Used during {@link BP_Embed::parse_oembed()} via {@link bp_forums_embed()}.
  *
- * @package BuddyPress_Forums
- * @since BuddyPress (1.5)
+ * Wrapper function for {@link bb_update_postmeta()}.
+ *
+ * @since BuddyPress (1.5.0)
  */
 function bp_embed_forum_save_cache( $cache, $cachekey, $id ) {
 	bb_update_postmeta( $id, $cachekey, $cache );
diff --git a/wp-content/plugins/buddypress/bp-forums/bp-forums-loader.php b/wp-content/plugins/buddypress/bp-forums/bp-forums-loader.php
index 1c55b702904f66c1aacf1637eecb428b747aa344..bbabdd459e9bf2188089453f4d26dd312ef3f84d 100644
--- a/wp-content/plugins/buddypress/bp-forums/bp-forums-loader.php
+++ b/wp-content/plugins/buddypress/bp-forums/bp-forums-loader.php
@@ -5,8 +5,11 @@
  *
  * A discussion forums component. Comes bundled with bbPress stand-alone.
  *
+ * Note: The bp-forums component has been retired. Use the bbPress WordPress
+ * plugin instead.
+ *
  * @package BuddyPress
- * @subpackage Forums Core
+ * @subpackage Forums
  */
 
 // Exit if accessed directly
@@ -15,25 +18,32 @@ if ( !defined( 'ABSPATH' ) ) exit;
 class BP_Forums_Component extends BP_Component {
 
 	/**
-	 * Start the forums component creation process
+	 * Start the forums component creation process.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'forums',
 			__( 'Discussion Forums', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 80
+			)
 		);
 	}
 
 	/**
-	 * Setup globals
+	 * Set up bp-forums global settings.
 	 *
 	 * The BP_FORUMS_SLUG constant is deprecated, and only used here for
 	 * backwards compatibility.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @see BP_Component::setup_globals() for description of parameters.
+	 *
+	 * @param array $args See {@link BP_Component::setup_globals()}.
 	 */
 	public function setup_globals( $args = array() ) {
 		$bp = buddypress();
@@ -64,7 +74,11 @@ class BP_Forums_Component extends BP_Component {
 	}
 
 	/**
-	 * Include files
+	 * Include bp-forums files.
+	 *
+	 * @see BP_Component::includes() for description of parameters.
+	 *
+	 * @param array $includes See {@link BP_Component::includes()}.
 	 */
 	public function includes( $includes = array() ) {
 
@@ -92,7 +106,16 @@ class BP_Forums_Component extends BP_Component {
 	}
 
 	/**
-	 * Setup BuddyBar navigation
+	 * Set up component navigation.
+	 *
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @see BP_Component::setup_nav() for a description of arguments.
+	 *
+	 * @param array $main_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
+	 * @param array $sub_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
 
@@ -152,13 +175,17 @@ class BP_Forums_Component extends BP_Component {
 	}
 
 	/**
-	 * Set up the Toolbar
+	 * Set up bp-forums integration with the WordPress admin bar.
+	 *
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @see BP_Component::setup_admin_bar() for a description of arguments.
+	 *
+	 * @param array $wp_admin_nav See BP_Component::setup_admin_bar()
+	 *        for description.
 	 */
 	public function setup_admin_bar( $wp_admin_nav = array() ) {
 
-		// Prevent debug notices
-		$wp_admin_nav = array();
-
 		// Menus for logged in user
 		if ( is_user_logged_in() ) {
 
@@ -202,9 +229,9 @@ class BP_Forums_Component extends BP_Component {
 	}
 
 	/**
-	 * Sets up the title for pages and <title>
+	 * Set up the title for pages and the <title> element.
 	 */
-	function setup_title() {
+	public function setup_title() {
 		$bp = buddypress();
 
 		// Adjust title based on view
@@ -225,6 +252,9 @@ class BP_Forums_Component extends BP_Component {
 	}
 }
 
+/**
+ * Set up the bp-forums component.
+ */
 function bp_setup_forums() {
 	buddypress()->forums = new BP_Forums_Component();
 }
diff --git a/wp-content/plugins/buddypress/bp-forums/bp-forums-screens.php b/wp-content/plugins/buddypress/bp-forums/bp-forums-screens.php
index aed9f71c8cec2d873f780c6ef63101a62a495ab0..2f2e537272dcdd94589f5353195e34c45dc267ab 100644
--- a/wp-content/plugins/buddypress/bp-forums/bp-forums-screens.php
+++ b/wp-content/plugins/buddypress/bp-forums/bp-forums-screens.php
@@ -1,7 +1,17 @@
 <?php
+/**
+ * BuddyPress Forums Screen Functions.
+ *
+ * @package BuddyPress
+ * @subpackage Forums
+ */
+
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Load the Forums directory.
+ */
 function bp_forums_directory_forums_setup() {
 
 	// Get BuddyPress once
@@ -72,12 +82,18 @@ function bp_forums_directory_forums_setup() {
 }
 add_action( 'bp_screens', 'bp_forums_directory_forums_setup', 2 );
 
+/**
+ * Load the Topics Started screen.
+ */
 function bp_member_forums_screen_topics() {
 	do_action( 'bp_member_forums_screen_topics' );
 
 	bp_core_load_template( apply_filters( 'bp_member_forums_screen_topics', 'members/single/home' ) );
 }
 
+/**
+ * Load the Replied To screen.
+ */
 function bp_member_forums_screen_replies() {
 	do_action( 'bp_member_forums_screen_replies' );
 
@@ -85,11 +101,9 @@ function bp_member_forums_screen_replies() {
 }
 
 /**
- * Loads the template content for a user's Favorites forum tab.
+ * Load the template content for a user's Favorites forum tab.
  *
  * Note that this feature is not fully implemented at the moment.
- *
- * @package BuddyPress Forums
  */
 function bp_member_forums_screen_favorites() {
 	do_action( 'bp_member_forums_screen_favorites' );
@@ -97,6 +111,9 @@ function bp_member_forums_screen_favorites() {
 	bp_core_load_template( apply_filters( 'bp_member_forums_screen_favorites', 'members/single/home' ) );
 }
 
+/**
+ * Load a single forum page.
+ */
 function bp_forums_screen_single_forum() {
 
 	if ( !bp_is_forums_component() || !bp_is_current_action( 'forum' ) || !bp_action_variable( 0 ) )
@@ -108,6 +125,9 @@ function bp_forums_screen_single_forum() {
 }
 add_action( 'bp_screens', 'bp_forums_screen_single_forum' );
 
+/**
+ * Load a single forum topic page.
+ */
 function bp_forums_screen_single_topic() {
 
 	if ( !bp_is_forums_component() || !bp_is_current_action( 'topic' ) || !bp_action_variable( 0 ) )
@@ -123,19 +143,19 @@ add_action( 'bp_screens', 'bp_forums_screen_single_topic' );
 /** Theme Compatability *******************************************************/
 
 /**
- * The main theme compat class for legacy BuddyPress forums, as powered by bbPress 1.x
+ * The main theme compat class for legacy BuddyPress forums.
  *
  * This class sets up the necessary theme compatability actions to safely output
  * old forum template parts to the_title and the_content areas of a theme.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 class BP_Forum_Legacy_Theme_Compat {
 
 	/**
-	 * Setup the old forums component theme compatibility
+	 * Set up theme compatibility for the legacy forums component.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __construct() {
 		add_action( 'bp_setup_theme_compat', array( $this, 'is_legacy_forum' ) );
@@ -144,7 +164,7 @@ class BP_Forum_Legacy_Theme_Compat {
 	/**
 	 * Are we looking at something that needs old forum theme compatability?
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function is_legacy_forum() {
 
@@ -177,9 +197,9 @@ class BP_Forum_Legacy_Theme_Compat {
 	/** Directory *************************************************************/
 
 	/**
-	 * Update the global $post with directory data
+	 * Update the global $post with directory data.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function directory_dummy_post() {
 
@@ -198,18 +218,18 @@ class BP_Forum_Legacy_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => 'bp_forum',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
 
 	/**
-	 * Filter the_content with the old forum index template part
+	 * Filter the_content with the old forum index template part.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function directory_content() {
-		bp_buffer_template_part( 'forums/index' );
+		return bp_buffer_template_part( 'forums/index', null, false );
 	}
 }
 new BP_Forum_Legacy_Theme_Compat();
diff --git a/wp-content/plugins/buddypress/bp-forums/bp-forums-template.php b/wp-content/plugins/buddypress/bp-forums/bp-forums-template.php
index 3d9efdc67895a7a192db1057add941164b63e970..e1be39e731ddbbdc4cb0e375f7d6086cdb46881f 100644
--- a/wp-content/plugins/buddypress/bp-forums/bp-forums-template.php
+++ b/wp-content/plugins/buddypress/bp-forums/bp-forums-template.php
@@ -1,13 +1,18 @@
 <?php
+/**
+ * BuddyPress Forums Template Tags.
+ *
+ * @package BuddyPress
+ * @subpackage Forums
+ */
+
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Output the forums component slug
+ * Output the forums component slug.
  *
- * @package BuddyPress
- * @subpackage Forums Template
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_forums_slug()
  */
@@ -15,11 +20,11 @@ function bp_forums_slug() {
 	echo bp_get_forums_slug();
 }
 	/**
-	 * Return the forums component slug
+	 * Return the forums component slug.
 	 *
-	 * @package BuddyPress
-	 * @subpackage Forums Template
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @return string Slug for the forums component.
 	 */
 	function bp_get_forums_slug() {
 		global $bp;
@@ -27,11 +32,9 @@ function bp_forums_slug() {
 	}
 
 /**
- * Output the forums component root slug
+ * Output the forums component root slug.
  *
- * @package BuddyPress
- * @subpackage Forums Template
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_forums_root_slug()
  */
@@ -39,11 +42,11 @@ function bp_forums_root_slug() {
 	echo bp_get_forums_root_slug();
 }
 	/**
-	 * Return the forums component root slug
+	 * Return the forums component root slug.
 	 *
-	 * @package BuddyPress
-	 * @subpackage Forums Template
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @return string Root slug for the forums component.
 	 */
 	function bp_get_forums_root_slug() {
 		global $bp;
@@ -51,52 +54,157 @@ function bp_forums_root_slug() {
 	}
 
 /**
- * Output forum directory permalink
+ * Output permalink for the forum directory.
+ *
+ * @since BuddyPress (1.5.0)
  *
- * @package BuddyPress
- * @subpackage Forums Template
- * @since BuddyPress (1.5)
  * @uses bp_get_forums_directory_permalink()
  */
 function bp_forums_directory_permalink() {
 	echo bp_get_forums_directory_permalink();
 }
 	/**
-	 * Return forum directory permalink
+	 * Return permalink for the forum directory.
+	 *
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @package BuddyPress
-	 * @subpackage Forums Template
-	 * @since BuddyPress (1.5)
 	 * @uses apply_filters()
 	 * @uses traisingslashit()
 	 * @uses bp_get_root_domain()
 	 * @uses bp_get_forums_root_slug()
-	 * @return string
+	 *
+	 * @return string The permalink for the forums component directory.
 	 */
 	function bp_get_forums_directory_permalink() {
 		return apply_filters( 'bp_get_forums_directory_permalink', trailingslashit( bp_get_root_domain() . '/' . bp_get_forums_root_slug() ) );
 	}
 
+/**
+ * The main forums template loop class.
+ *
+ * Responsible for loading a group of forum topics into a loop for display.
+ */
 class BP_Forums_Template_Forum {
+	/**
+	 * The loop iterator.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $current_topic = -1;
+
+	/**
+	 * The number of topics returned by the paged query.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $topic_count;
+
+	/**
+	 * Array of topics located by the query.
+	 *
+	 * @access public
+	 * @var array
+	 */
 	var $topics;
+
+	/**
+	 * The topic object currently being iterated on.
+	 *
+	 * @access public
+	 * @var object
+	 */
 	var $topic;
 
+	/**
+	 * The ID of the forum whose topics are being queried.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $forum_id;
 
+	/**
+	 * A flag for whether the loop is currently being iterated.
+	 *
+	 * @access public
+	 * @var bool
+	 */
 	var $in_the_loop;
 
+	/**
+	 * The page number being requested.
+	 *
+	 * @access public
+	 * @var public
+	 */
 	var $pag_page;
+
+	/**
+	 * The number of items being requested per page.
+	 *
+	 * @access public
+	 * @var public
+	 */
 	var $pag_num;
+
+	/**
+	 * An HTML string containing pagination links.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $pag_links;
+
+	/**
+	 * The total number of topics matching the query parameters.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $total_topic_count;
 
+	/**
+	 * Whether requesting a single topic. Not currently used.
+	 *
+	 * @access public
+	 * @var bool
+	 */
 	var $single_topic = false;
 
+	/**
+	 * Term to sort by. Not currently used.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $sort_by;
+
+	/**
+	 * Sort order. Not currently used.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $order;
 
+	/**
+	 * Constructor method.
+	 *
+	 * @param string $type The 'type' is the sort order/kind. 'newest',
+	 *        'popular', 'unreplied', 'tags'.
+	 * @param int $forum_id The ID of the forum for which topics are being
+	 *        queried.
+	 * @param int $user_id The ID of the user to whom topics should be
+	 *        limited. Pass false to remove this filter.
+	 * @param int $page The number of the page being requested.
+	 * @param int $per_page The number of items being requested perpage.
+	 * @param string $no_stickies Requested sticky format.
+	 * @param string $search_terms Filter results by a string.
+	 * @param int $offset Optional. Offset results by a given numeric value.
+	 * @param int $number Optional. Total number of items to retrieve.
+	 */
 	function __construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms, $offset = false, $number = false ) {
 		global $bp;
 
@@ -192,6 +300,13 @@ class BP_Forums_Template_Forum {
 		}
 	}
 
+	/**
+	 * Whether there are topics available in the loop.
+	 *
+	 * @see bp_has_forum_topics()
+	 *
+	 * @return bool True if there are items in the loop, otherwise false.
+	 */
 	function has_topics() {
 		if ( $this->topic_count )
 			return true;
@@ -199,6 +314,11 @@ class BP_Forums_Template_Forum {
 		return false;
 	}
 
+	/**
+	 * Set up the next topic and iterate index.
+	 *
+	 * @return object The next topic to iterate over.
+	 */
 	function next_topic() {
 		$this->current_topic++;
 		$this->topic = $this->topics[$this->current_topic];
@@ -206,6 +326,9 @@ class BP_Forums_Template_Forum {
 		return $this->topic;
 	}
 
+	/**
+	 * Rewind the topics and reset topic index.
+	 */
 	function rewind_topics() {
 		$this->current_topic = -1;
 		if ( $this->topic_count > 0 ) {
@@ -213,6 +336,17 @@ class BP_Forums_Template_Forum {
 		}
 	}
 
+	/**
+	 * Whether there are blogs left in the loop to iterate over.
+	 *
+	 * This method is used by {@link bp_forum_topics()} as part of the while loop
+	 * that controls iteration inside the blogs loop, eg:
+	 *     while ( bp_forum_topics() ) { ...
+	 *
+	 * @see bp_forum_topics()
+	 *
+	 * @return bool True if there are more topics to show, otherwise false.
+	 */
 	function user_topics() {
 		if ( $this->current_topic + 1 < $this->topic_count ) {
 			return true;
@@ -226,6 +360,11 @@ class BP_Forums_Template_Forum {
 		return false;
 	}
 
+	/**
+	 * Set up the current topic in the loop.
+	 *
+	 * @see bp_the_forum_topic()
+	 */
 	function the_topic() {
 		global $topic;
 
@@ -241,16 +380,41 @@ class BP_Forums_Template_Forum {
 /**
  * Initiate the forum topics loop.
  *
- * Like other BuddyPress custom loops, the default arguments for this function are determined
- * dynamically, depending on your current page. All of these $defaults can be overridden in the
- * $args parameter.
+ * Like other BuddyPress custom loops, the default arguments for this function
+ * are determined dynamically, depending on your current page. All of these
+ * $defaults can be overridden in the $args parameter.
  *
- * @package BuddyPress
- * @uses apply_filters() Filter bp_has_topics to manipulate the $forums_template global before
- *   it's rendered, or to modify the value of has_topics().
+ * @uses apply_filters() Filter 'bp_has_topics' to manipulate the
+ *       $forums_template global before it's rendered, or to modify the value
+ *       of has_topics().
  *
- * @param array $args See inline definition of $defaults for explanation of arguments
- * @return bool Returns true when forum topics are found corresponding to the args, false otherwise.
+ * @param array $args {
+ *     Arguments for limiting the contents of the forum topics loop.
+ *
+ *     @type string $type The 'type' is the sort order/kind. 'newest',
+ *           'popular', 'unreplied', 'tags'. Default: 'newest'.
+ *     @type int $forum_id The ID of the forum for which topics are being
+ *           queried. Default: the ID of the forum belonging to the current
+ *           group, if available.
+ *     @type int $user_id The ID of a user to whom to limit results. If viewing
+ *           a member's profile, defaults to that member's ID; otherwise
+ *           defaults to 0.
+ *     @type int $page The number of the page being requested. Default: 1, or
+ *           the value of $_GET['p'].
+ *     @type int $per_pag The number items to return per page. Default: 20, or
+ *           the value of $_GET['n'].
+ *     @type int $max Optional. Max records to return. Default: false (no max).
+ *     @type int $number Optional. Number of records to return. Default: false.
+ *     @type int $offset Optional. Offset results by a given value.
+ *           Default: false.
+ *     @type string $search_terms Optional. A string to which results should be
+ *           limited. Default: false, or the value of $_GET['fs'].
+ *     @type string|bool $do_stickies Whether to move stickies to the top of
+ *           the sort order. Default: true if looking at a group forum,
+ *           otherwise false.
+ * }
+ * @return bool True when forum topics are found corresponding to the args,
+ *         false otherwise.
  */
 function bp_has_forum_topics( $args = '' ) {
 	global $forum_template, $bp;
@@ -316,7 +480,7 @@ function bp_has_forum_topics( $args = '' ) {
 		'do_stickies'  => $do_stickies
 	);
 
-	$r = wp_parse_args( $args, $defaults );
+	$r = bp_parse_args( $args, $defaults, 'has_forum_topics' );
 	extract( $r );
 
 	// If we're viewing a tag URL in the directory, let's override the type and
@@ -418,46 +582,92 @@ function bp_has_forum_topics( $args = '' ) {
 	return apply_filters( 'bp_has_topics', $forum_template->has_topics(), $forum_template );
 }
 
+/**
+ * Determine whether there are still topics left in the loop.
+ *
+ * @global BP_Forums_Template_Forum $forum_template Template global.
+ *
+ * @return bool Returns true when topics are found.
+ */
 function bp_forum_topics() {
 	global $forum_template;
 	return $forum_template->user_topics();
 }
 
+/**
+ * Get the current topic object in the loop.
+ *
+ * @global BP_Forums_Template_Forum $forum_template Template global.
+ *
+ * @return object The current topic object.
+ */
 function bp_the_forum_topic() {
 	global $forum_template;
 	return $forum_template->the_topic();
 }
 
+/**
+ * Output the ID of the current topic in the loop.
+ */
 function bp_the_topic_id() {
 	echo bp_get_the_topic_id();
 }
+	/**
+	 * Return the ID of the current topic in the loop.
+	 *
+	 * @return int ID of the current topic in the loop.
+	 */
 	function bp_get_the_topic_id() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_id', $forum_template->topic->topic_id );
 	}
 
+/**
+ * Output the title of the current topic in the loop.
+ */
 function bp_the_topic_title() {
 	echo bp_get_the_topic_title();
 }
+	/**
+	 * Return the title of the current topic in the loop.
+	 *
+	 * @return string Title of the current topic in the loop.
+	 */
 	function bp_get_the_topic_title() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_title', stripslashes( $forum_template->topic->topic_title ) );
 	}
 
+/**
+ * Output the slug of the current topic in the loop.
+ */
 function bp_the_topic_slug() {
 	echo bp_get_the_topic_slug();
 }
+	/**
+	 * Return the slug of the current topic in the loop.
+	 *
+	 * @return string Slug of the current topic in the loop.
+	 */
 	function bp_get_the_topic_slug() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_slug', $forum_template->topic->topic_slug );
 	}
 
+/**
+ * Output the text of the first post in the current topic in the loop.
+ */
 function bp_the_topic_text() {
 	echo bp_get_the_topic_text();
 }
+	/**
+	 * Return the text of the first post in the current topic in the loop.
+	 *
+	 * @return string Text of the first post in the current topic.
+	 */
 	function bp_get_the_topic_text() {
 		global $forum_template;
 
@@ -465,18 +675,51 @@ function bp_the_topic_text() {
 		return apply_filters( 'bp_get_the_topic_text', esc_attr( $post->post_text ) );
 	}
 
+/**
+ * Output the ID of the user who posted the current topic in the loop.
+ */
 function bp_the_topic_poster_id() {
 	echo bp_get_the_topic_poster_id();
 }
+	/**
+	 * Return the ID of the user who posted the current topic in the loop.
+	 *
+	 * @return int ID of the user who posted the current topic.
+	 */
 	function bp_get_the_topic_poster_id() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_poster_id', $forum_template->topic->topic_poster );
 	}
 
+/**
+ * Output the avatar of the user who posted the current topic in the loop.
+ *
+ * @see bp_get_the_topic_poster_avatar() for a description of arguments.
+ *
+ * @param array $args See {@link bp_get_the_topic_poster_avatar()}.
+ */
 function bp_the_topic_poster_avatar( $args = '' ) {
 	echo bp_get_the_topic_poster_avatar( $args );
 }
+	/**
+	 * Return the avatar of the user who posted the current topic in the loop.
+	 *
+	 * @param array $args {
+	 *     Arguments for building the avatar.
+	 *     @type string $type Avatar type. 'thumb' or 'full'. Default:
+	 *           'thumb'.
+	 *     @type int $width Width of the avatar, in pixels. Default: the
+	 *           width corresponding to $type.
+	 *           See {@link bp_core_fetch_avatar()}.
+	 *     @type int $height Height of the avatar, in pixels. Default: the
+	 *           height corresponding to $type.
+	 *           See {@link bp_core_fetch_avatar()}.
+	 *     @type string $alt The text of the image's 'alt' attribute.
+	 *           Default: 'Profile picture of [user name]'.
+	 * }
+	 * @return string HTML of user avatar.
+	 */
 	function bp_get_the_topic_poster_avatar( $args = '' ) {
 		global $forum_template;
 
@@ -493,9 +736,17 @@ function bp_the_topic_poster_avatar( $args = '' ) {
 		return apply_filters( 'bp_get_the_topic_poster_avatar', bp_core_fetch_avatar( array( 'item_id' => $forum_template->topic->topic_poster, 'type' => $type, 'width' => $width, 'height' => $height, 'alt' => $alt ) ) );
 	}
 
+/**
+ * Output the name of the user who posted the current topic in the loop.
+ */
 function bp_the_topic_poster_name() {
 	echo bp_get_the_topic_poster_name();
 }
+	/**
+	 * Return the name of the user who posted the current topic in the loop.
+	 *
+	 * @return string Name of the user who posted the current topic.
+	 */
 	function bp_get_the_topic_poster_name() {
 		global $forum_template;
 
@@ -507,18 +758,39 @@ function bp_the_topic_poster_name() {
 		return apply_filters( 'bp_get_the_topic_poster_name', $name );
 	}
 
+/**
+ * Output the ID of the object associated with the current topic in the loop.
+ */
 function bp_the_topic_object_id() {
 	echo bp_get_the_topic_object_id();
 }
+	/**
+	 * Return the ID of the object associated with the current topic in the loop.
+	 *
+	 * Objects are things like associated groups.
+	 *
+	 * @return int ID of the associated object.
+	 */
 	function bp_get_the_topic_object_id() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_object_id', $forum_template->topic->object_id );
 	}
 
+/**
+ * Output the name of the object associated with the current topic in the loop.
+ */
 function bp_the_topic_object_name() {
 	echo bp_get_the_topic_object_name();
 }
+	/**
+	 * Return the name of the object associated with the current topic in the loop.
+	 *
+	 * Objects are things like groups. So this function would return the
+	 * name of the group associated with the forum topic, if it exists.
+	 *
+	 * @return string Object name.
+	 */
 	function bp_get_the_topic_object_name() {
 		global $forum_template;
 
@@ -530,18 +802,40 @@ function bp_the_topic_object_name() {
 		return apply_filters( 'bp_get_the_topic_object_name', $retval );
 	}
 
+/**
+ * Output the slug of the object associated with the current topic in the loop.
+ */
 function bp_the_topic_object_slug() {
 	echo bp_get_the_topic_object_slug();
 }
+	/**
+	 * Return the slug of the object associated with the current topic in the loop.
+	 *
+	 * Objects are things like groups. So this function would return the
+	 * slug of the group associated with the forum topic, if it exists.
+	 *
+	 * @return string Object slug.
+	 */
 	function bp_get_the_topic_object_slug() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_object_slug', $forum_template->topic->object_slug );
 	}
 
+/**
+ * Output the permalink of the object associated with the current topic in the loop.
+ */
 function bp_the_topic_object_permalink() {
 	echo bp_get_the_topic_object_permalink();
 }
+	/**
+	 * Return the permalink of the object associated with the current topic in the loop.
+	 *
+	 * Objects are things like groups. So this function would return the
+	 * permalink of the group associated with the forum topic, if it exists.
+	 *
+	 * @return string Object permalink.
+	 */
 	function bp_get_the_topic_object_permalink() {
 
 		// Currently this will only work with group forums, extended support in the future
@@ -553,9 +847,18 @@ function bp_the_topic_object_permalink() {
 		return apply_filters( 'bp_get_the_topic_object_permalink', $permalink );
 	}
 
+/**
+ * Output the linked name of the user who last posted to the current topic in the loop.
+ */
 function bp_the_topic_last_poster_name() {
 	echo bp_get_the_topic_last_poster_name();
 }
+	/**
+	 * Return the linked name of the user who last posted to the current topic in the loop.
+	 *
+	 * @return string HTML link to the profile of the user who last posted
+	 *         to the current topic.
+	 */
 	function bp_get_the_topic_last_poster_name() {
 		global $forum_template;
 
@@ -569,9 +872,37 @@ function bp_the_topic_last_poster_name() {
 		return apply_filters( 'bp_get_the_topic_last_poster_name', '<a href="' . $domain . '">' . $forum_template->topic->topic_last_poster_displayname . '</a>' );
 	}
 
+/**
+ * Output the permalink of the object associated with the current topic in the loop.
+ *
+ * @see bp_get_the_topic_object_avatar() for description of arguments.
+ *
+ * @param array $args See {@bp_get_the_topic_object_avatar()}.
+ */
 function bp_the_topic_object_avatar( $args = '' ) {
 	echo bp_get_the_topic_object_avatar( $args );
 }
+	/**
+	 * Return the avatar of the object associated with the current topic in the loop.
+	 *
+	 * Objects are things like groups. So this function would return the
+	 * avatar of the group associated with the forum topic, if it exists.
+	 *
+	 * @param array $args {
+	 *     Arguments for building the avatar.
+	 *     @type string $type Avatar type. 'thumb' or 'full'. Default:
+	 *           'thumb'.
+	 *     @type int $width Width of the avatar, in pixels. Default: the
+	 *           width corresponding to $type.
+	 *           See {@link bp_core_fetch_avatar()}.
+	 *     @type int $height Height of the avatar, in pixels. Default:
+	 *           the height corresponding to $type.
+	 *           See {@link bp_core_fetch_avatar()}.
+	 *     @type string $alt The text of the image's 'alt' attribute.
+	 *           Default: 'Group logo for [group name]'.
+	 * }
+	 * @return string Object avatar.
+	 */
 	function bp_get_the_topic_object_avatar( $args = '' ) {
 		global $forum_template;
 
@@ -591,9 +922,34 @@ function bp_the_topic_object_avatar( $args = '' ) {
 		return apply_filters( 'bp_get_the_topic_object_avatar', bp_core_fetch_avatar( array( 'item_id' => $forum_template->topic->object_id, 'type' => $type, 'object' => 'group', 'width' => $width, 'height' => $height, 'alt' => $alt ) ) );
 	}
 
+/**
+ * Output the avatar for the user who last posted to the current topic in the loop.
+ *
+ * @see bp_get_the_topic_last_poster_avatar() for description of arguments.
+ *
+ * @param array $args See {@bp_get_the_topic_last_poster_avatar()}.
+ */
 function bp_the_topic_last_poster_avatar( $args = '' ) {
 	echo bp_get_the_topic_last_poster_avatar( $args );
 }
+	/**
+	 * Return the avatar for the user who last posted to the current topic in the loop.
+	 *
+	 * @param array $args {
+	 *     Arguments for building the avatar.
+	 *     @type string $type Avatar type. 'thumb' or 'full'. Default:
+	 *           'thumb'.
+	 *     @type int $width Width of the avatar, in pixels. Default: the
+	 *           width corresponding to $type.
+	 *           See {@link bp_core_fetch_avatar()}.
+	 *     @type int $height Height of the avatar, in pixels. Default:
+	 *           the height corresponding to $type.
+	 *           See {@link bp_core_fetch_avatar()}.
+	 *     @type string $alt The text of the image's 'alt' attribute.
+	 *           Default: 'Profile picture of [group name]'.
+	 * }
+	 * @return string User avatar.
+	 */
 	function bp_get_the_topic_last_poster_avatar( $args = '' ) {
 		global $forum_template;
 
@@ -610,72 +966,136 @@ function bp_the_topic_last_poster_avatar( $args = '' ) {
 		return apply_filters( 'bp_get_the_topic_last_poster_avatar', bp_core_fetch_avatar( array( 'email' => $forum_template->topic->topic_last_poster_email, 'item_id' => $forum_template->topic->topic_last_poster, 'type' => $type, 'width' => $width, 'height' => $height, 'alt' => $alt ) ) );
 	}
 
+/**
+ * Output the start time of the current topic in the loop.
+ */
 function bp_the_topic_start_time() {
 	echo bp_get_the_topic_start_time();
 }
+	/**
+	 * Return the start time of the current topic in the loop.
+	 *
+	 * @return string Start time of the current topic.
+	 */
 	function bp_get_the_topic_start_time() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_start_time', $forum_template->topic->topic_start_time );
 	}
 
+/**
+ * Output the topic time of the current topic in the loop.
+ */
 function bp_the_topic_time() {
 	echo bp_get_the_topic_time();
 }
+	/**
+	 * Return the topic time of the current topic in the loop.
+	 *
+	 * @return string Topic time of the current topic.
+	 */
 	function bp_get_the_topic_time() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_time', $forum_template->topic->topic_time );
 	}
 
+/**
+ * Output the ID of the forum associated with the current topic in the loop.
+ */
 function bp_the_topic_forum_id() {
 	echo bp_get_the_topic_forum_id();
 }
+	/**
+	 * Return the ID of the forum associated with the current topic in the loop.
+	 *
+	 * @return int ID of the forum associated with the current topic.
+	 */
 	function bp_get_the_topic_forum_id() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_forum_id', $forum_template->topic->forum_id );
 	}
 
+/**
+ * Output the status of the current topic in the loop.
+ */
 function bp_the_topic_status() {
 	echo bp_get_the_topic_status();
 }
+	/**
+	 * Return the status of the current topic in the loop.
+	 *
+	 * @return string Status of the current topic.
+	 */
 	function bp_get_the_topic_status() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_status', $forum_template->topic->topic_status );
 	}
 
+/**
+ * Output whether the current topic in the loop is open.
+ */
 function bp_the_topic_is_topic_open() {
 	echo bp_get_the_topic_is_topic_open();
 }
+	/**
+	 * Return whether the current topic in the loop is open.
+	 *
+	 * @return unknown
+	 */
 	function bp_get_the_topic_is_topic_open() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_is_topic_open', $forum_template->topic->topic_open );
 	}
 
+/**
+ * Output the ID of the last post in the current topic in the loop.
+ */
 function bp_the_topic_last_post_id() {
 	echo bp_get_the_topic_last_post_id();
 }
+	/**
+	 * Return the ID of the last post in the current topic in the loop.
+	 *
+	 * @return int ID of the last post in the current topic.
+	 */
 	function bp_get_the_topic_last_post_id() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_last_post_id', $forum_template->topic->topic_last_post_id );
 	}
 
+/**
+ * Output whether the current topic in the loop is sticky.
+ */
 function bp_the_topic_is_sticky() {
 	echo bp_get_the_topic_is_sticky();
 }
+	/**
+	 * Return whether the current topic in the loop is sticky.
+	 *
+	 * @return unknown
+	 */
 	function bp_get_the_topic_is_sticky() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_is_sticky', $forum_template->topic->topic_sticky );
 	}
 
+/**
+ * Output a 'x posts' string with the number of posts in the current topic.
+ */
 function bp_the_topic_total_post_count() {
 	echo bp_get_the_topic_total_post_count();
 }
+	/**
+	 * Return a 'x posts' string with the number of posts in the current topic.
+	 *
+	 * @return string String of the form 'x posts'.
+	 */
 	function bp_get_the_topic_total_post_count() {
 		global $forum_template;
 
@@ -685,27 +1105,51 @@ function bp_the_topic_total_post_count() {
 			return apply_filters( 'bp_get_the_topic_total_post_count', sprintf( __( '%d posts', 'buddypress' ), $forum_template->topic->topic_posts ) );
 	}
 
+/**
+ * Output the total number of posts in the current topic in the loop.
+ */
 function bp_the_topic_total_posts() {
 	echo bp_get_the_topic_total_posts();
 }
+	/**
+	 * Return the total number of posts in the current topic in the loop.
+	 *
+	 * @return int Total number of posts in the current topic.
+	 */
 	function bp_get_the_topic_total_posts() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_total_posts', $forum_template->topic->topic_posts );
 	}
 
+/**
+ * Output the tag count for the current topic in the loop.
+ */
 function bp_the_topic_tag_count() {
 	echo bp_get_the_topic_tag_count();
 }
+	/**
+	 * Return the tag count for the current topic in the loop.
+	 *
+	 * @return int Tag count for the current topic.
+	 */
 	function bp_get_the_topic_tag_count() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_tag_count', $forum_template->topic->tag_count );
 	}
 
+/**
+ * Output the permalink of the current topic in the loop.
+ */
 function bp_the_topic_permalink() {
 	echo bp_get_the_topic_permalink();
 }
+	/**
+	 * Return the permalink for the current topic in the loop.
+	 *
+	 * @return string Permalink for the current topic.
+	 */
 	function bp_get_the_topic_permalink() {
 		global $forum_template, $bp;
 
@@ -729,18 +1173,39 @@ function bp_the_topic_permalink() {
 		return apply_filters( 'bp_get_the_topic_permalink', trailingslashit( $permalink . 'topic/' . $forum_template->topic->topic_slug ) );
 	}
 
+/**
+ * Output a 'since' string describing when the current topic was created.
+ */
 function bp_the_topic_time_since_created() {
 	echo bp_get_the_topic_time_since_created();
 }
+	/**
+	 * Return a 'since' string describing when the current topic was created.
+	 *
+	 * @see bp_core_time_since() for a description of return value.
+	 *
+	 * @return string
+	 */
 	function bp_get_the_topic_time_since_created() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_time_since_created', bp_core_time_since( strtotime( $forum_template->topic->topic_start_time ) ) );
 	}
 
+/**
+ * Output an excerpt from the latest post of the current topic in the loop.
+ */
 function bp_the_topic_latest_post_excerpt( $args = '' ) {
 	echo bp_get_the_topic_latest_post_excerpt( $args );
 }
+	/**
+	 * Return an excerpt from the latest post of the current topic in the loop.
+	 *
+	 * @param array $args {
+	 *     @type int $length The length of the excerpted text. Default: 225.
+	 * }
+	 * @return string Post excerpt.
+	 */
 	function bp_get_the_topic_latest_post_excerpt( $args = '' ) {
 		global $forum_template;
 
@@ -757,27 +1222,62 @@ function bp_the_topic_latest_post_excerpt( $args = '' ) {
 		return apply_filters( 'bp_get_the_topic_latest_post_excerpt', $post, $length );
 	}
 
+/**
+ * Output a 'since' string describing when the last post in the current topic was created.
+ */
 function bp_the_topic_time_since_last_post() {
 	echo bp_get_the_topic_time_since_last_post();
 }
+	/**
+	 * Return a 'since' string describing when the last post in the current topic was created.
+	 *
+	 * @see bp_core_time_since() for a description of return value.
+	 *
+	 * @return string
+	 */
 	function bp_get_the_topic_time_since_last_post() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_the_topic_time_since_last_post', bp_core_time_since( strtotime( $forum_template->topic->topic_time ) ) );
 	}
 
+/**
+ * Output whether the current topic in the loop belongs to the logged-in user.
+ */
 function bp_the_topic_is_mine() {
 	echo bp_get_the_topic_is_mine();
 }
+	/**
+	 * Does the current topic belong to the logged-in user?
+	 *
+	 * @return bool True if the current topic in the loop was created by
+	 *         the logged-in user, otherwise false.
+	 */
 	function bp_get_the_topic_is_mine() {
 		global $forum_template;
 
 		return bp_loggedin_user_id() == $forum_template->topic->topic_poster;
 	}
 
-function bp_the_topic_admin_links( $args = '' ) {
-	echo bp_get_the_topic_admin_links( $args );
+/**
+ * Output the admin links for the current topic in the loop.
+ *
+ * @see bp_get_the_topic_admin_links() for a description of arguments.
+ *
+ * @param array $args See {@link bp_get_the_topic_admin_links()}.
+ */
+function bp_the_topic_admin_links( $args = '' ) {
+	echo bp_get_the_topic_admin_links( $args );
 }
+	/**
+	 * Return the admin links for the current topic in the loop.
+	 *
+	 * @param array $args {
+	 *     @type string $seperator The character to use when separating
+	 *           links. Default: '|'.
+	 * }
+	 * @return HTML string containing the admin links for the current topic.
+	 */
 	function bp_get_the_topic_admin_links( $args = '' ) {
 		global $forum_template;
 
@@ -807,10 +1307,20 @@ function bp_the_topic_admin_links( $args = '' ) {
 		return implode( ' ' . $seperator . ' ', (array) $links );
 	}
 
+/**
+ * Output the CSS class for the current topic in the loop.
+ */
 function bp_the_topic_css_class() {
 	echo bp_get_the_topic_css_class();
 }
-
+	/**
+	 * Return the CSS class for the current topic in the loop.
+	 *
+	 * This class may contain keywords like 'alt', 'sticky', or 'closed',
+	 * based on context.
+	 *
+	 * @return string Contents of the 'class' attribute.
+	 */
 	function bp_get_the_topic_css_class() {
 		global $forum_template;
 
@@ -828,46 +1338,87 @@ function bp_the_topic_css_class() {
 		return apply_filters( 'bp_get_the_topic_css_class', trim( $class ) );
 	}
 
+/**
+ * Output the permalink to the 'personal' topics tab.
+ */
 function bp_my_forum_topics_link() {
 	echo bp_get_my_forum_topics_link();
 }
+	/**
+	 * Return the permalink to the 'personal' topics tab.
+	 *
+	 * @return string Link to the 'personal' topics tab.
+	 */
 	function bp_get_my_forum_topics_link() {
 		global $bp;
 
 		return apply_filters( 'bp_get_my_forum_topics_link', bp_get_root_domain() . '/' . bp_get_forums_root_slug() . '/personal/' );
 	}
 
+/**
+ * Output the permalink to the 'unreplied' topics tab.
+ */
 function bp_unreplied_forum_topics_link() {
 	echo bp_get_unreplied_forum_topics_link();
 }
+	/**
+	 * Return the permalink to the 'unreplied' topics tab.
+	 *
+	 * @return string Link to the 'unreplied' topics tab.
+	 */
 	function bp_get_unreplied_forum_topics_link() {
 		global $bp;
 
 		return apply_filters( 'bp_get_unreplied_forum_topics_link', bp_get_root_domain() . '/' . bp_get_forums_root_slug() . '/unreplied/' );
 	}
 
-
+/**
+ * Output the permalink to the 'popular' topics tab.
+ */
 function bp_popular_forum_topics_link() {
 	echo bp_get_popular_forum_topics_link();
 }
+	/**
+	 * Return the permalink to the 'popular' topics tab.
+	 *
+	 * @return string Link to the 'popular' topics tab.
+	 */
 	function bp_get_popular_forum_topics_link() {
 		global $bp;
 
 		return apply_filters( 'bp_get_popular_forum_topics_link', bp_get_root_domain() . '/' . bp_get_forums_root_slug() . '/popular/' );
 	}
 
+/**
+ * Output the link to the forums directory.
+ */
 function bp_newest_forum_topics_link() {
 	echo bp_get_newest_forum_topics_link();
 }
+	/**
+	 * Return the link to the forums directory.
+	 *
+	 * @return string Link to the forums directory.
+	 */
 	function bp_get_newest_forum_topics_link() {
 		global $bp;
 
 		return apply_filters( 'bp_get_newest_forum_topics_link', bp_get_root_domain() . '/' . bp_get_forums_root_slug() . '/' );
 	}
 
+/**
+ * Output the currently viewed topic list type.
+ */
 function bp_forum_topic_type() {
 	echo bp_get_forum_topic_type();
 }
+	/**
+	 * Return the currently viewed topic list type.
+	 *
+	 * Eg, 'newest', 'popular', etc.
+	 *
+	 * @return string Type of the currently viewed topic list.
+	 */
 	function bp_get_forum_topic_type() {
 		global $bp;
 
@@ -878,22 +1429,21 @@ function bp_forum_topic_type() {
 	}
 
 /**
- * Echoes the output of bp_get_forum_topic_new_reply_link()
+ * Output the value of bp_get_forum_topic_new_reply_link().
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  */
 function bp_forum_topic_new_reply_link() {
 	echo bp_get_forum_topic_new_reply_link();
 }
 	/**
-	 * Returns the permalink for the New Reply button at the top of forum topics
+	 * Return the permalink for the New Reply button at the top of forum topics.
 	 *
-	 * @package BuddyPress
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @uses apply_filters() Filter bp_get_forum_topic_new_reply_link to modify
-	 * @return string The URL for the New Reply link
+	 * @uses apply_filters() Filter bp_get_forum_topic_new_reply_link to
+	 *       modify.
+	 * @return string The URL for the New Reply link.
 	 */
 	function bp_get_forum_topic_new_reply_link() {
 		global $topic_template;
@@ -914,18 +1464,16 @@ function bp_forum_topic_new_reply_link() {
 	}
 
 /**
- * Echoes the output of bp_get_forums_tag_name()
+ * Output the currently viewed tag name.
  *
- * @package BuddyPress
  * @todo Deprecate?
  */
 function bp_forums_tag_name() {
 	echo bp_get_forums_tag_name();
 }
 	/**
-	 * Outputs the currently viewed tag name
+	 * Return the currently viewed tag name.
 	 *
-	 * @package BuddyPress
 	 * @todo Deprecate? Seems unused
 	 */
 	function bp_get_forums_tag_name() {
@@ -934,18 +1482,36 @@ function bp_forums_tag_name() {
 		return apply_filters( 'bp_get_forums_tag_name', $tag_name );
 	}
 
+/**
+ * Output the pagination links for the current topic list.
+ */
 function bp_forum_pagination() {
 	echo bp_get_forum_pagination();
 }
+	/**
+	 * Return the pagination links for the current topic list.
+	 *
+	 * @return string HTML pagination links.
+	 */
 	function bp_get_forum_pagination() {
 		global $forum_template;
 
 		return apply_filters( 'bp_get_forum_pagination', $forum_template->pag_links );
 	}
 
+/**
+ * Output the pagination count for the current topic list.
+ */
 function bp_forum_pagination_count() {
 	echo bp_get_forum_pagination_count();
 }
+	/**
+	 * Return the pagination count for the current topic list.
+	 *
+	 * The "count" is a string of the form "Viewing x of y topics".
+	 *
+	 * @return string
+	 */
 	function bp_get_forum_pagination_count() {
 		global $bp, $forum_template;
 
@@ -958,9 +1524,14 @@ function bp_forum_pagination_count() {
 		if ( 'tags' == $forum_template->type && !empty( $forum_template->search_terms ) )
 			$pag_filter = sprintf( __( ' matching tag "%s"', 'buddypress' ), $forum_template->search_terms );
 
-		return apply_filters( 'bp_get_forum_pagination_count', sprintf( __( 'Viewing topic %s to %s (of %s total topics%s)', 'buddypress' ), $from_num, $to_num, $total, $pag_filter ) );
+		return apply_filters( 'bp_get_forum_pagination_count', sprintf( _n( 'Viewing topic %s to %s (of %d topic%s)', 'Viewing topic %s to %s (of %d total topics%s)', $total, 'buddypress' ), $from_num, $to_num, $total, $pag_filter ), $from_num, $to_num, $total );
 	}
 
+/**
+ * Are we currently on an Edit Topic screen?
+ *
+ * @return bool True if currently editing a topic, otherwise false.
+ */
 function bp_is_edit_topic() {
 	global $bp;
 
@@ -970,36 +1541,149 @@ function bp_is_edit_topic() {
 	return true;
 }
 
+/**
+ * The single forum topic template loop class.
+ *
+ * Responsible for loading a topic's posts into a loop for display.
+ */
 class BP_Forums_Template_Topic {
+	/**
+	 * The loop iterator.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $current_post = -1;
+
+	/**
+	 * The number of posts returned by the paged query.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $post_count;
+
+	/**
+	 * Array of posts located by the query.
+	 *
+	 * @access public
+	 * @var array
+	 */
 	var $posts;
+
+	/**
+	 * The post object currently being iterated on.
+	 *
+	 * @access public
+	 * @var object
+	 */
 	var $post;
 
+	/**
+	 * The ID of the forum whose topic is being queried.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $forum_id;
+
+	/**
+	 * The ID of the topic whose posts are being queried.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $topic_id;
+
+	/**
+	 * The topic object to which the posts belong.
+	 *
+	 * @access public
+	 * @var object
+	 */
 	var $topic;
 
+	/**
+	 * A flag for whether the loop is currently being iterated.
+	 *
+	 * @access public
+	 * @var bool
+	 */
 	var $in_the_loop;
 
 	/**
-	 * Contains a 'total_pages' property holding total number of pages in this loop.
+	 * Contains a 'total_pages' property holding total number of pages in
+	 * this loop.
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var stdClass
 	 */
 	public $pag;
 
+	/**
+	 * The page number being requested.
+	 *
+	 * @access public
+	 * @var public
+	 */
 	var $pag_page;
+
+	/**
+	 * The number of items being requested per page.
+	 *
+	 * @access public
+	 * @var public
+	 */
 	var $pag_num;
+
+	/**
+	 * An HTML string containing pagination links.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $pag_links;
+
+	/**
+	 * The total number of posts matching the query parameters.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $total_post_count;
 
+	/**
+	 * Whether requesting a single topic. Not currently used.
+	 *
+	 * @access public
+	 * @var bool
+	 */
 	var $single_post = false;
 
+	/**
+	 * Term to sort by.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $sort_by;
+
+	/**
+	 * Sort order.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $order;
 
+	/**
+	 * Constructor method.
+	 *
+	 * @param int $topic_id ID of the topic whose posts are being requested.
+	 * @param int $per_page Number of items to return per page.
+	 * @param int $max Max records to return.
+	 * @param string $order Direction to order results.
+	 */
 	function __construct( $topic_id, $per_page, $max, $order ) {
 		global $bp, $current_user, $forum_template;
 
@@ -1060,6 +1744,13 @@ class BP_Forums_Template_Topic {
 		}
 	}
 
+	/**
+	 * Whether there are posts available in the loop.
+	 *
+	 * @see bp_has_forum_topic_posts()
+	 *
+	 * @return bool True if there are items in the loop, otherwise false.
+	 */
 	function has_posts() {
 		if ( $this->post_count )
 			return true;
@@ -1067,6 +1758,11 @@ class BP_Forums_Template_Topic {
 		return false;
 	}
 
+	/**
+	 * Set up the next post and iterate index.
+	 *
+	 * @return object The next post to iterate over.
+	 */
 	function next_post() {
 		$this->current_post++;
 		$this->post = $this->posts[$this->current_post];
@@ -1074,6 +1770,9 @@ class BP_Forums_Template_Topic {
 		return $this->post;
 	}
 
+	/**
+	 * Rewind the posts and reset post index.
+	 */
 	function rewind_posts() {
 		$this->current_post = -1;
 		if ( $this->post_count > 0 ) {
@@ -1081,6 +1780,17 @@ class BP_Forums_Template_Topic {
 		}
 	}
 
+	/**
+	 * Whether there are posts left in the loop to iterate over.
+	 *
+	 * This method is used by {@link bp_forum_topic_posts()} as part of
+	 * the while loop that controls iteration inside the blogs loop, eg:
+	 *     while ( bp_forum_topic_posts() ) { ...
+	 *
+	 * @see bp_forum_topic_posts()
+	 *
+	 * @return bool True if there are more posts to show, otherwise false.
+	 */
 	function user_posts() {
 		if ( $this->current_post + 1 < $this->post_count ) {
 			return true;
@@ -1094,6 +1804,11 @@ class BP_Forums_Template_Topic {
 		return false;
 	}
 
+	/**
+	 * Set up the current topic in the loop.
+	 *
+	 * @see bp_the_forum_topic_post()
+	 */
 	function the_post() {
 		global $post;
 
@@ -1106,6 +1821,19 @@ class BP_Forums_Template_Topic {
 	}
 }
 
+/**
+ * Initiate the loop for a single topic's posts.
+ *
+ * @param array $args {
+ *     Arguments for limiting the contents of the topic posts loop.
+ *     @type int $topic_id ID of the topic to which the posts belong.
+ *     @type int $per_page Number of items to return per page. Default: 15.
+ *     @type int $max Max items to return. Default: false.
+ *     @type string $order 'ASC' or 'DESC'.
+ * }
+ * @return bool True when posts are found corresponding to the args,
+ *         otherwise false.
+ */
 function bp_has_forum_topic_posts( $args = '' ) {
 	global $topic_template;
 
@@ -1116,7 +1844,7 @@ function bp_has_forum_topic_posts( $args = '' ) {
 		'order'    => 'ASC'
 	);
 
-	$r = wp_parse_args( $args, $defaults );
+	$r = bp_parse_args( $args, $defaults, 'has_forum_topic_posts' );
 	extract( $r, EXTR_SKIP );
 
 	if ( empty( $topic_id ) && bp_is_groups_component() && bp_is_current_action( 'forum' ) && bp_is_action_variable( 'topic', 0 ) && bp_action_variable( 1 ) )
@@ -1138,38 +1866,75 @@ function bp_has_forum_topic_posts( $args = '' ) {
 	return apply_filters( 'bp_has_topic_posts', $topic_template->has_posts(), $topic_template );
 }
 
+/**
+ * Determine whether there are posts left in the loop.
+ *
+ * @return bool True when posts are found.
+ */
 function bp_forum_topic_posts() {
 	global $topic_template;
 	return $topic_template->user_posts();
 }
 
+/**
+ * Set up the current post in the loop.
+ *
+ * @return object
+ */
 function bp_the_forum_topic_post() {
 	global $topic_template;
 	return $topic_template->the_post();
 }
 
+/**
+ * Output the ID of the current post in the loop.
+ */
 function bp_the_topic_post_id() {
 	echo bp_get_the_topic_post_id();
 }
+	/**
+	 * Return the ID of the current post in the loop.
+	 *
+	 * @return int ID of the current post in the loop.
+	 */
 	function bp_get_the_topic_post_id() {
 		global $topic_template;
 
 		return apply_filters( 'bp_get_the_topic_post_id', $topic_template->post->post_id );
 	}
 
+/**
+ * Output the content of the current post in the loop.
+ */
 function bp_the_topic_post_content() {
 	echo bp_get_the_topic_post_content();
 }
+	/**
+	 * Return the content of the current post in the loop.
+	 *
+	 * @return string Content of the current post.
+	 */
 	function bp_get_the_topic_post_content() {
 		global $topic_template;
 
 		return apply_filters( 'bp_get_the_topic_post_content', stripslashes( $topic_template->post->post_text ) );
 	}
 
+/**
+ * Output the CSS class of the current post in the loop.
+ */
 function bp_the_topic_post_css_class() {
 	echo bp_get_the_topic_post_css_class();
 }
-
+	/**
+	 * Return the CSS class of the current post in the loop.
+	 *
+	 * May contain strings 'alt', 'deleted', or 'open', depending on
+	 * context.
+	 *
+	 * @return string String to put in the 'class' attribute of the current
+	 *         post.
+	 */
 	function bp_get_the_topic_post_css_class() {
 		global $topic_template;
 
@@ -1187,9 +1952,34 @@ function bp_the_topic_post_css_class() {
 		return apply_filters( 'bp_get_the_topic_post_css_class', trim( $class ) );
 	}
 
+/**
+ * Output the avatar of the user who posted the current post in the loop.
+ *
+ * @see bp_get_the_topic_post_poster_avatar() for a description of arguments.
+ *
+ * @param array $args See {@link bp_get_the_topic_post_poster_avatar()}.
+ */
 function bp_the_topic_post_poster_avatar( $args = '' ) {
 	echo bp_get_the_topic_post_poster_avatar( $args );
 }
+	/**
+	 * Return the avatar of the user who posted the current post in the loop.
+	 *
+	 * @param array $args {
+	 *     Arguments for building the avatar.
+	 *     @type string $type Avatar type. 'thumb' or 'full'. Default:
+	 *           'thumb'.
+	 *     @type int $width Width of the avatar, in pixels. Default: the
+	 *           width corresponding to $type.
+	 *           See {@link bp_core_fetch_avatar()}.
+	 *     @type int $height Height of the avatar, in pixels. Default: the
+	 *           height corresponding to $type.
+	 *           See {@link bp_core_fetch_avatar()}.
+	 *     @type string $alt The text of the image's 'alt' attribute.
+	 *           Default: 'Profile picture of [user name]'.
+	 * }
+	 * @return string HTML of user avatar.
+	 */
 	function bp_get_the_topic_post_poster_avatar( $args = '' ) {
 		global $topic_template;
 
@@ -1206,9 +1996,17 @@ function bp_the_topic_post_poster_avatar( $args = '' ) {
 		return apply_filters( 'bp_get_the_topic_post_poster_avatar', bp_core_fetch_avatar( array( 'item_id' => $topic_template->post->poster_id, 'type' => $type, 'width' => $width, 'height' => $height, 'alt' => $alt ) ) );
 	}
 
+/**
+ * Output the name of the user who posted the current post in the loop.
+ */
 function bp_the_topic_post_poster_name() {
 	echo bp_get_the_topic_post_poster_name();
 }
+	/**
+	 * Return the name of the user who posted the current post in the loop.
+	 *
+	 * @return string Name of the user who posted the current post.
+	 */
 	function bp_get_the_topic_post_poster_name() {
 		global $topic_template;
 
@@ -1218,36 +2016,80 @@ function bp_the_topic_post_poster_name() {
 		return apply_filters( 'bp_get_the_topic_post_poster_name', '<a href="' . $link . '" title="' . $topic_template->post->poster_name . '">' . $topic_template->post->poster_name . '</a>' );
 	}
 
+/**
+ * Output a link to the profile of the user who posted the current post.
+ */
 function bp_the_topic_post_poster_link() {
 	echo bp_get_the_topic_post_poster_link();
 }
+	/**
+	 * Return a link to the profile of the user who posted the current post.
+	 *
+	 * @return string Link to the profile of the user who posted the
+	 *         current post.
+	 */
 	function bp_get_the_topic_post_poster_link() {
 		global $topic_template;
 
 		return apply_filters( 'bp_the_topic_post_poster_link', bp_core_get_user_domain( $topic_template->post->poster_id ) );
 	}
 
+/**
+ * Output a 'since' string describing when the current post in the loop was posted.
+ */
 function bp_the_topic_post_time_since() {
 	echo bp_get_the_topic_post_time_since();
 }
+	/**
+	 * Return a 'since' string describing when the current post in the loop was posted.
+	 *
+	 * @see bp_core_time_since() for a description of return value.
+	 *
+	 * @return string
+	 */
 	function bp_get_the_topic_post_time_since() {
 		global $topic_template;
 
 		return apply_filters( 'bp_get_the_topic_post_time_since', bp_core_time_since( strtotime( $topic_template->post->post_time ) ) );
 	}
 
+/**
+ * Output whether the current post in the loop belongs to the logged-in user.
+ */
 function bp_the_topic_post_is_mine() {
 	echo bp_the_topic_post_is_mine();
 }
+	/**
+	 * Does the current post belong to the logged-in user?
+	 *
+	 * @return bool True if the current post in the loop was created by
+	 *         the logged-in user, otherwise false.
+	 */
 	function bp_get_the_topic_post_is_mine() {
 		global $bp, $topic_template;
 
 		return bp_loggedin_user_id() == $topic_template->post->poster_id;
 	}
 
+/**
+ * Output the admin links for the current post in the loop.
+ *
+ * @see bp_get_the_post_admin_links() for a description of arguments.
+ *
+ * @param array $args See {@link bp_get_the_post_admin_links()}.
+ */
 function bp_the_topic_post_admin_links( $args = '' ) {
 	echo bp_get_the_topic_post_admin_links( $args );
 }
+	/**
+	 * Return the admin links for the current post in the loop.
+	 *
+	 * @param array $args {
+	 *     @type string $separator The character to use when separating
+	 *           links. Default: '|'.
+	 * }
+	 * @return HTML string containing the admin links for the current post.
+	 */
 	function bp_get_the_topic_post_admin_links( $args = '' ) {
 		global $topic_template;
 
@@ -1273,23 +2115,46 @@ function bp_the_topic_post_admin_links( $args = '' ) {
 		return apply_filters( 'bp_get_the_topic_post_admin_links', implode( $separator, $links ), $links, $r );
 	}
 
+/**
+ * Output the text to edit when editing a post.
+ */
 function bp_the_topic_post_edit_text() {
 	echo bp_get_the_topic_post_edit_text();
 }
+	/**
+	 * Return the text to edit when editing a post.
+	 *
+	 * @return string Editable text.
+	 */
 	function bp_get_the_topic_post_edit_text() {
 		$post = bp_forums_get_post( bp_action_variable( 4 ) );
 		return apply_filters( 'bp_get_the_topic_post_edit_text', esc_attr( $post->post_text ) );
 	}
 
+/**
+ * Output the pagination links for the current topic.
+ */
 function bp_the_topic_pagination() {
 	echo bp_get_the_topic_pagination();
 }
+	/**
+	 * Return the pagination links for the current topic page.
+	 *
+	 * @return string HTML pagination links.
+	 */
 	function bp_get_the_topic_pagination() {
 		global $topic_template;
 
 		return apply_filters( 'bp_get_the_topic_pagination', $topic_template->pag_links );
 	}
 
+/**
+ * Return the pagination count for the current topic page.
+ *
+ * The "count" is a string of the form "Viewing x of y posts".
+ *
+ * @return string
+ */
 function bp_the_topic_pagination_count() {
 	global $bp, $topic_template;
 
@@ -1298,35 +2163,59 @@ function bp_the_topic_pagination_count() {
 	$to_num = bp_core_number_format( ( $start_num + ( $topic_template->pag_num - 1  ) > $topic_template->total_post_count ) ? $topic_template->total_post_count : $start_num + ( $topic_template->pag_num - 1 ) );
 	$total = bp_core_number_format( $topic_template->total_post_count );
 
-	echo apply_filters( 'bp_the_topic_pagination_count', sprintf( __( 'Viewing post %1$s to %2$s (%3$s total posts)', 'buddypress' ), $from_num, $to_num, $total ) );
+	echo apply_filters( 'bp_the_topic_pagination_count', sprintf( _n( 'Viewing post %1$s to %2$s (%3$s post)', 'Viewing post %1$s to %2$s (%3$s total posts)', $total, 'buddypress' ), $from_num, $to_num, $total ), $from_num, $to_num, $total );
 }
 
+/**
+ * Output whether this is the last page in the current topic.
+ */
 function bp_the_topic_is_last_page() {
 	echo bp_get_the_topic_is_last_page();
 }
+	/**
+	 * Is this the last page in the current topic?
+	 *
+	 * @return bool True if this is the last page of posts for the current
+	 *         topic, otherwise false.
+	 */
 	function bp_get_the_topic_is_last_page() {
 		global $topic_template;
 
 		return apply_filters( 'bp_get_the_topic_is_last_page', $topic_template->pag_page == $topic_template->pag->total_pages );
 	}
 
+/**
+ * Output the forums directory search form.
+ */
 function bp_directory_forums_search_form() {
-	global $bp;
-
 	$default_search_value = bp_get_search_default_text( 'forums' );
-	$search_value = !empty( $_REQUEST['fs'] ) ? stripslashes( $_REQUEST['fs'] ) : $default_search_value;  ?>
+	$search_value = !empty( $_REQUEST['fs'] ) ? stripslashes( $_REQUEST['fs'] ) : $default_search_value;
 
-	<form action="" method="get" id="search-forums-form">
-		<label><input type="text" name="s" id="forums_search" placeholder="<?php echo esc_attr( $search_value ); ?>" /></label>
-		<input type="submit" id="forums_search_submit" name="forums_search_submit" value="<?php _e( 'Search', 'buddypress' ); ?>" />
-	</form>
+	$search_form_html = '<form action="" method="get" id="search-forums-form">
+		<label><input type="text" name="s" id="forums_search" placeholder="'. esc_attr( $search_value ) .'" /></label>
+		<input type="submit" id="forums_search_submit" name="forums_search_submit" value="' . __( 'Search', 'buddypress' ) . '" />
+	</form>';
 
-<?php
+	echo apply_filters( 'bp_directory_forums_search_form', $search_form_html );
 }
 
+/**
+ * Output the link to a given forum.
+ *
+ * @see bp_get_forum_permalink() for a description of arguments.
+ *
+ * @param int $forum_id See {@link bp_get_forum_permalink()}.
+ */
 function bp_forum_permalink( $forum_id = 0 ) {
 	echo bp_get_forum_permalink( $forum_id );
 }
+	/**
+	 * Return the permalink to a given forum.
+	 *
+	 * @param int $forum_id Optional. Defaults to the current forum, if
+	 *        there is one.
+	 * @return string|bool False on failure, a URL on success.
+	 */
 	function bp_get_forum_permalink( $forum_id = 0 ) {
 		global $bp;
 
@@ -1348,9 +2237,23 @@ function bp_forum_permalink( $forum_id = 0 ) {
 		return apply_filters( 'bp_get_forum_permalink', trailingslashit( $permalink ) );
 	}
 
+/**
+ * Output the name of a given forum.
+ *
+ * @see bp_get_forum_name() for a description of parameters.
+ *
+ * @param int $forum_id See {@link bp_get_forum_name()}.
+ */
 function bp_forum_name( $forum_id = 0 ) {
 	echo bp_get_forum_name( $forum_id );
 }
+	/**
+	 * Return the name of a given forum.
+	 *
+	 * @param int $forum_id Optional. Defaults to the current forum, if
+	 *        there is one.
+	 * @return string|bool False on failure, a name on success.
+	 */
 	function bp_get_forum_name( $forum_id = 0 ) {
 		global $bp;
 
@@ -1366,6 +2269,20 @@ function bp_forum_name( $forum_id = 0 ) {
 			return false;
 	}
 
+/**
+ * Get a heatmap of forum tags for the installation.
+ *
+ * A wrapper for {@link bb_tag_heat_map}, which provides it with BP-friendly
+ * defaults.
+ *
+ * @param array $args {
+ *     An array of optional arguments.
+ *     @type int $smallest Size of the smallest link. Default: 10.
+ *     @type int $largest Size of the largest link. Default: 42.
+ *     @type string $sizing Unit for $largest and $smallest. Default: 'px'.
+ *     @type int $limit Max number of tags to display. Default: 50.
+ * }
+ */
 function bp_forums_tag_heat_map( $args = '' ) {
 	$defaults = array(
 		'smallest' => '10',
@@ -1381,21 +2298,20 @@ function bp_forums_tag_heat_map( $args = '' ) {
 }
 
 /**
- * Echo the current topic's tag list, comma-separated
+ * Output the current topic's tag list, comma-separated
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  */
 function bp_forum_topic_tag_list() {
 	echo bp_get_forum_topic_tag_list();
 }
 	/**
-	 * Get the current topic's tag list
+	 * Get the current topic's tag list.
 	 *
-	 * @package BuddyPress
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @param string $format 'string' returns comma-separated string; otherwise returns array
+	 * @param string $format 'string' returns comma-separated string;
+	 *        otherwise returns array.
 	 * @return mixed $tags
 	 */
 	function bp_get_forum_topic_tag_list( $format = 'string' ) {
@@ -1418,12 +2334,11 @@ function bp_forum_topic_tag_list() {
 	}
 
 /**
- * Returns true if the current topic has tags
+ * Does the current topic have any tags?
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @return bool
+ * @return bool True if the current topic has tags, otherwise false.
  */
 function bp_forum_topic_has_tags() {
 	global $topic_template;
@@ -1436,32 +2351,72 @@ function bp_forum_topic_has_tags() {
 	return apply_filters( 'bp_forum_topic_has_tags', $has_tags );
 }
 
+/**
+ * Output a URL to use in as a forum form 'action'.
+ */
 function bp_forum_action() {
 	echo bp_get_forum_action();
 }
+	/**
+	 * Get a URL to use in as a forum form 'action'.
+	 *
+	 * @return string URL of the current page, minus query args.
+	 */
 	function bp_get_forum_action() {
 		global $topic_template;
 
 		return apply_filters( 'bp_get_forum_action', bp_get_root_domain() . esc_attr( $_SERVER['REQUEST_URI'] ) );
 	}
 
+/**
+ * Output a URL to use in as a forum topic form 'action'.
+ */
 function bp_forum_topic_action() {
 	echo bp_get_forum_topic_action();
 }
+	/**
+	 * Get a URL to use in as a forum topic form 'action'.
+	 *
+	 * @return string URL of the current page, minus query args.
+	 */
 	function bp_get_forum_topic_action() {
 		return apply_filters( 'bp_get_forum_topic_action', $_SERVER['REQUEST_URI'] );
 	}
 
+/**
+ * Output the total topic count for a given user.
+ *
+ * @see bp_get_forum_topic_count_for_user() for description of parameters.
+ *
+ * @param int $user_id See {@link bp_get_forum_topic_count_for_user()}.
+ */
 function bp_forum_topic_count_for_user( $user_id = 0 ) {
 	echo bp_get_forum_topic_count_for_user( $user_id );
 }
+	/**
+	 * Return the total topic count for a given user.
+	 *
+	 * @param int $user_id See {@link bp_forums_total_topic_count_for_user}.
+	 */
 	function bp_get_forum_topic_count_for_user( $user_id = 0 ) {
 		return apply_filters( 'bp_get_forum_topic_count_for_user', bp_forums_total_topic_count_for_user( $user_id ) );
 	}
 
+/**
+ * Output the total topic count for a given user.
+ *
+ * @see bp_get_forum_topic_count() for description of parameters.
+ *
+ * @param int $user_id See {@link bp_get_forum_topic_count()}.
+ */
 function bp_forum_topic_count( $user_id = 0 ) {
 	echo bp_get_forum_topic_count( $user_id );
 }
+	/**
+	 * Return the total topic count for a given user.
+	 *
+	 * @param int $user_id See {@link bp_forums_total_topic_count()}.
+	 */
 	function bp_get_forum_topic_count( $user_id = 0 ) {
 		return apply_filters( 'bp_get_forum_topic_count', bp_forums_total_topic_count( $user_id ) );
 	}
diff --git a/wp-content/plugins/buddypress/bp-forums/deprecated/1.6.php b/wp-content/plugins/buddypress/bp-forums/deprecated/1.6.php
index 78379cc869bcb764fafecd09b728cf4a082fa609..5262fdfc603a2685f9b9be3738b4c63b70d63c26 100644
--- a/wp-content/plugins/buddypress/bp-forums/deprecated/1.6.php
+++ b/wp-content/plugins/buddypress/bp-forums/deprecated/1.6.php
@@ -152,7 +152,7 @@ function bp_forums_bbpress_install_wizard() {
 						<h3><?php _e( 'Existing bbPress Installation', 'buddypress' ) ?></h3>
 						<p><?php _e( "BuddyPress can make use of your existing bbPress install. Just provide the location of your <code>bb-config.php</code> file, and BuddyPress will do the rest.", 'buddypress' ) ?></p>
 						<p><label><code>bb-config.php</code> file location:</label><br /><input style="width: 50%" type="text" name="bbconfigloc" id="bbconfigloc" value="<?php echo str_replace( 'buddypress', '', $_SERVER['DOCUMENT_ROOT'] ) ?>" /></p>
-						<p><input type="submit" class="button-primary" value="<?php _e( 'Complete Installation', 'buddypress' ) ?>" /></p>
+						<p><input type="submit" class="button-primary" value="<?php esc_attr_e( 'Complete Installation', 'buddypress' ) ?>" /></p>
 						<input type="hidden" name="step" value="existing" />
 						<input type="hidden" name="doinstall" value="1" />
 						<?php wp_nonce_field( 'bp_forums_existing_install_init' ) ?>
@@ -174,7 +174,7 @@ function bp_forums_bbpress_install_wizard() {
 						// Just write the contents to screen
 						_e( '<p>A configuration file could not be created. No problem, but you will need to save the text shown below into a file named <code>bb-config.php</code> in the root directory of your WordPress installation before you can start using the forum functionality.</p>', 'buddypress' ); ?>
 
-						<textarea style="display:block; margin-top: 30px; width: 80%;" rows="50"><?php echo htmlspecialchars( $result ); ?></textarea>
+						<textarea style="display:block; margin-top: 30px; width: 80%;" rows="50"><?php echo esc_textarea( $result ); ?></textarea>
 
 					<?php
 						break;
@@ -191,7 +191,7 @@ function bp_forums_bbpress_install_wizard() {
 		break;
 
 		default:
-			if ( !file_exists( BP_PLUGIN_DIR . '/bp-forums/bbpress/' ) ) { ?>
+			if ( !file_exists( buddypress()->plugin_dir . '/bp-forums/bbpress/' ) ) { ?>
 
 				<div id="message" class="error">
 					<p><?php printf( __( 'bbPress files were not found. To install the forums component you must download a copy of bbPress and make sure it is in the folder: "%s"', 'buddypress' ), 'wp-content/plugins/buddypress/bp-forums/bbpress/' ) ?></p>
diff --git a/wp-content/plugins/buddypress/bp-forums/deprecated/1.7.php b/wp-content/plugins/buddypress/bp-forums/deprecated/1.7.php
index 8117f63e47e43303423cca44604a6f2540f38f03..d6290604885f03c77fc94791a677fa1b659bc5be 100644
--- a/wp-content/plugins/buddypress/bp-forums/deprecated/1.7.php
+++ b/wp-content/plugins/buddypress/bp-forums/deprecated/1.7.php
@@ -54,7 +54,7 @@ function bp_forums_configure_existing_install() {
 }
 
 function bp_forums_bbpress_install( $location = '' ) {
-	global $wpdb, $bbdb, $bp;
+	global $wpdb, $bbdb;
 
 	check_admin_referer( 'bp_forums_new_install_init' );
 
@@ -62,9 +62,11 @@ function bp_forums_bbpress_install( $location = '' ) {
 		$location = ABSPATH . 'bb-config.php';
 	}
 
+	$bp = buddypress();
+
 	// Create the bb-config.php file
 	$initial_write = bp_forums_bbpress_write(
-		BP_PLUGIN_DIR . '/bp-forums/bbpress/bb-config-sample.php',
+		$bp->plugin_dir . '/bp-forums/bbpress/bb-config-sample.php',
 		$location,
 		array(
 			"define( 'BBDB_NAME',"  => array( "'bbpress'",                     	"'" . DB_NAME . "'" ),
@@ -96,7 +98,7 @@ function bp_forums_bbpress_install( $location = '' ) {
 
 	$file .= "\n" .   '$bb->custom_user_table = \'' . $wpdb->users . '\';';
 	$file .= "\n" .   '$bb->custom_user_meta_table = \'' . $wpdb->usermeta . '\';';
-	$file .= "\n\n" . '$bb->uri = \'' . BP_PLUGIN_URL . '/bp-forums/bbpress/\';';
+	$file .= "\n\n" . '$bb->uri = \'' . $bp->plugin_url . '/bp-forums/bbpress/\';';
 	$file .= "\n" .   '$bb->name = \'' . get_blog_option( bp_get_root_blog_id(), 'blogname' ) . ' ' . __( 'Forums', 'buddypress' ) . '\';';
 
 	if ( is_multisite() ) {
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-actions.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-actions.php
index 354fc10487fc89747f6f521ada5fc1dec4ea24e9..7a1aa15aece310a364fe0f2bf7e7129e81f97373 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-actions.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-actions.php
@@ -3,9 +3,9 @@
 /**
  * BuddyPress Friends Actions
  *
- * Action functions are exactly the same as screen functions, however they do not
- * have a template screen associated with them. Usually they will send the user
- * back to the default screen after execution.
+ * Action functions are exactly the same as screen functions, however they do
+ * not have a template screen associated with them. Usually they will send the
+ * user back to the default screen after execution.
  *
  * @package BuddyPress
  * @subpackage FriendsActions
@@ -14,6 +14,9 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Catch and process friendship requests.
+ */
 function friends_action_add_friend() {
 	if ( !bp_is_friends_component() || !bp_is_current_action( 'add-friend' ) )
 		return false;
@@ -49,6 +52,9 @@ function friends_action_add_friend() {
 }
 add_action( 'bp_init', 'friends_action_add_friend' );
 
+/**
+ * Catch and process Remove Friendship requests.
+ */
 function friends_action_remove_friend() {
 	if ( !bp_is_friends_component() || !bp_is_current_action( 'remove-friend' ) )
 		return false;
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-activity.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-activity.php
index d3a5345e4ba981193256048da5140e02cdb8d84d..92ab0bfecd1e9584bf243252c44f0d0635e0dbe2 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-activity.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-activity.php
@@ -13,49 +13,98 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Record an activity item related to the Friends component.
+ *
+ * A wrapper for {@link bp_activity_add()} that provides some Friends-specific
+ * defaults.
+ *
+ * @see bp_activity_add() for more detailed description of parameters and
+ *      return values.
+ *
+ * @param array $args {
+ *     An array of arguments for the new activity item. Accepts all parameters
+ *     of {@link bp_activity_add()}. The one difference is the following
+ *     argument, which has a different default here:
+ *     @type string $component Default: the id of your Friends component
+ *           (usually 'friends').
+ * }
+ * @return bool See {@link bp_activity_add()}.
+ */
 function friends_record_activity( $args = '' ) {
-	global $bp;
 
-	if ( !bp_is_active( 'activity' ) )
+	if ( ! bp_is_active( 'activity' ) ) {
 		return false;
+	}
 
-	$defaults = array (
+	$r = wp_parse_args( $args, array(
 		'user_id'           => bp_loggedin_user_id(),
 		'action'            => '',
 		'content'           => '',
 		'primary_link'      => '',
-		'component'         => $bp->friends->id,
+		'component'         => buddypress()->friends->id,
 		'type'              => false,
 		'item_id'           => false,
 		'secondary_item_id' => false,
 		'recorded_time'     => bp_core_current_time(),
 		'hide_sitewide'     => false
-	);
+	) );
 
-	$r = wp_parse_args( $args, $defaults );
-	extract( $r, EXTR_SKIP );
-
-	return bp_activity_add( array( 'user_id' => $user_id, 'action' => $action, 'content' => $content, 'primary_link' => $primary_link, 'component' => $component, 'type' => $type, 'item_id' => $item_id, 'secondary_item_id' => $secondary_item_id, 'recorded_time' => $recorded_time, 'hide_sitewide' => $hide_sitewide ) );
+	return bp_activity_add( $r );
 }
 
+/**
+ * Delete an activity item related to the Friends component.
+ *
+ * @param array $args {
+ *     An array of arguments for the item to delete.
+ *     @type int $item_id ID of the 'item' associated with the activity item.
+ *           For Friends activity items, this is usually the user ID of one
+ *           of the friends.
+ *     @type string $type The 'type' of the activity item (eg
+ *           'friendship_accepted').
+ *     @type int $user_id ID of the user associated with the activity item.
+ * }
+ * @return bool True on success, false on failure.
+ */
 function friends_delete_activity( $args ) {
-	global $bp;
-
-	if ( bp_is_active( 'activity' ) ) {
-		extract( (array) $args );
-		bp_activity_delete_by_item_id( array( 'item_id' => $item_id, 'component' => $bp->friends->id, 'type' => $type, 'user_id' => $user_id ) );
+	if ( ! bp_is_active( 'activity' ) ) {
+		return;
 	}
+
+	bp_activity_delete_by_item_id( array(
+		'component' => buddypress()->friends->id,
+		'item_id'   => $args['item_id'],
+		'type'      => $args['type'],
+		'user_id'   => $args['user_id']
+	) );
 }
 
+/**
+ * Register the activity actions for bp-friends.
+ */
 function friends_register_activity_actions() {
-	global $bp;
 
-	if ( !bp_is_active( 'activity' ) )
+	if ( !bp_is_active( 'activity' ) ) {
 		return false;
+	}
+
+	$bp = buddypress();
 
 	// These two added in BP 1.6
-	bp_activity_set_action( $bp->friends->id, 'friendship_accepted', __( 'Friendships accepted', 'buddypress' ) );
-	bp_activity_set_action( $bp->friends->id, 'friendship_created', __( 'New friendships', 'buddypress' ) );
+	bp_activity_set_action(
+		$bp->friends->id,
+		'friendship_accepted',
+		__( 'Friendships accepted', 'buddypress' ),
+		'bp_friends_format_activity_action_friendship_accepted'
+	);
+
+	bp_activity_set_action(
+		$bp->friends->id,
+		'friendship_created',
+		__( 'New friendships', 'buddypress' ),
+		'bp_friends_format_activity_action_friendship_created'
+	);
 
 	// < BP 1.6 backpat
 	bp_activity_set_action( $bp->friends->id, 'friends_register_activity_action', __( 'New friendship created', 'buddypress' ) );
@@ -65,59 +114,131 @@ function friends_register_activity_actions() {
 add_action( 'bp_register_activity_actions', 'friends_register_activity_actions' );
 
 /**
- * Format the BuddyBar/Toolbar notifications for the Friends component
+ * Format 'friendship_accepted' activity actions.
  *
- * @package BuddyPress
+ * @since BuddyPress (2.0.0)
+ *
+ * @param object $activity Activity data.
+ * @return string $action Formatted activity action.
+ */
+function bp_friends_format_activity_action_friendship_accepted( $action, $activity ) {
+	$initiator_link = bp_core_get_userlink( $activity->user_id );
+	$friend_link    = bp_core_get_userlink( $activity->secondary_item_id );
+
+	$action = sprintf( __( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link );
+
+	// Backward compatibility for legacy filter
+	// The old filter has the $friendship object passed to it. We want to
+	// avoid having to build this object if it's not necessary
+	if ( has_filter( 'friends_activity_friendship_accepted_action' ) ) {
+		$friendship = new BP_Friends_Friendship( $activity->item_id );
+		$action     = apply_filters( 'friends_activity_friendsip_accepted_action', $action, $friendship );
+	}
+
+	return apply_filters( 'bp_friends_format_activity_action_friendship_accepted', $action, $activity );
+}
+
+/**
+ * Format 'friendship_created' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
  *
- * @param string $action The kind of notification being rendered
- * @param int $item_id The primary item id
- * @param int $secondary_item_id The secondary item id
- * @param int $total_items The total number of messaging-related notifications waiting for the user
- * @param string $format 'string' for BuddyBar-compatible notifications; 'array' for WP Toolbar
+ * @param string $action Static activity action.
+ * @param object $activity Activity data.
+ * @return string $action Formatted activity action.
  */
-function friends_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
-
-	switch ( $action ) {
-		case 'friendship_accepted':
-			$link = trailingslashit( bp_loggedin_user_domain() . bp_get_friends_slug() . '/my-friends' );
-
-			// Set up the string and the filter
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( '%d friends accepted your friendship requests', 'buddypress' ), (int) $total_items );
-				$filter = 'bp_friends_multiple_friendship_accepted_notification';
-			} else {
-				$text = sprintf( __( '%s accepted your friendship request', 'buddypress' ),  bp_core_get_user_displayname( $item_id ) );
-				$filter = 'bp_friends_single_friendship_accepted_notification';
-			}
-
-			break;
-
-		case 'friendship_request':
-			$link = bp_loggedin_user_domain() . bp_get_friends_slug() . '/requests/?new';
-
-			// Set up the string and the filter
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( 'You have %d pending friendship requests', 'buddypress' ), (int) $total_items );
-				$filter = 'bp_friends_multiple_friendship_request_notification';
-			} else {
-				$text = sprintf( __( 'You have a friendship request from %s', 'buddypress' ),  bp_core_get_user_displayname( $item_id ) );
-				$filter = 'bp_friends_single_friendship_request_notification';
-			}
-
-			break;
+function bp_friends_format_activity_action_friendship_created( $action, $activity ) {
+	$initiator_link = bp_core_get_userlink( $activity->user_id );
+	$friend_link    = bp_core_get_userlink( $activity->secondary_item_id );
+
+	$action = sprintf( __( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link );
+
+	// Backward compatibility for legacy filter
+	// The old filter has the $friendship object passed to it. We want to
+	// avoid having to build this object if it's not necessary
+	if ( has_filter( 'friends_activity_friendship_accepted_action' ) ) {
+		$friendship = new BP_Friends_Friendship( $activity->item_id );
+		$action     = apply_filters( 'friends_activity_friendsip_accepted_action', $action, $friendship );
 	}
 
-	// Return either an HTML link or an array, depending on the requested format
-	if ( 'string' == $format ) {
-		$return = apply_filters( $filter, '<a href="' . $link . '">' . $text . '</a>', (int) $total_items );
-	} else {
-		$return = apply_filters( $filter, array(
-			'link' => $link,
-			'text' => $text
-		), (int) $total_items );
+	return apply_filters( 'bp_friends_format_activity_action_friendship_created', $action, $activity );
+}
+
+/**
+ * Fetch data related to friended users at the beginning of an activity loop.
+ *
+ * This reduces database overhead during the activity loop.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $activities Array of activity items.
+ * @return array
+ */
+function bp_friends_prefetch_activity_object_data( $activities ) {
+	if ( empty( $activities ) ) {
+		return $activities;
 	}
 
-	do_action( 'friends_format_notifications', $action, $item_id, $secondary_item_id, $total_items, $return );
+	$friend_ids = array();
+
+	foreach ( $activities as $activity ) {
+		if ( buddypress()->friends->id !== $activity->component ) {
+			continue;
+		}
+
+		$friend_ids[] = $activity->secondary_item_id;
+	}
+
+	if ( ! empty( $friend_ids ) ) {
+		// Fire a user query to prime user caches
+		new BP_User_Query( array(
+			'user_ids'          => $friend_ids,
+			'populate_extras'   => false,
+			'update_meta_cache' => false,
+		) );
+	}
+
+	return $activities;
+}
+add_filter( 'bp_activity_prefetch_object_data', 'bp_friends_prefetch_activity_object_data' );
+
+/**
+ * Add activity stream items when one members accepts another members request
+ * for virtual friendship.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $friendship_id
+ * @param int $initiator_user_id
+ * @param int $friend_user_id
+ * @param object $friendship Optional
+ */
+function bp_friends_friendship_accepted_activity( $friendship_id, $initiator_user_id, $friend_user_id, $friendship = false ) {
+
+	// Bail if Activity component is not active
+	if ( ! bp_is_active( 'activity' ) ) {
+		return;
+	}
 
-	return $return;
+	// Get links to both members profiles
+	$initiator_link = bp_core_get_userlink( $initiator_user_id );
+	$friend_link    = bp_core_get_userlink( $friend_user_id    );
+
+	// Record in activity streams for the initiator
+	friends_record_activity( array(
+		'user_id'           => $initiator_user_id,
+		'type'              => 'friendship_created',
+		'item_id'           => $friendship_id,
+		'secondary_item_id' => $friend_user_id
+	) );
+
+	// Record in activity streams for the friend
+	friends_record_activity( array(
+		'user_id'           => $friend_user_id,
+		'type'              => 'friendship_created',
+		'item_id'           => $friendship_id,
+		'secondary_item_id' => $initiator_user_id,
+		'hide_sitewide'     => true // We've already got the first entry site wide
+	) );
 }
+add_action( 'friends_friendship_accepted', 'bp_friends_friendship_accepted_activity', 10, 4 );
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-cache.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-cache.php
index c5dbf17224ab3899916564b320de14cc2d249791..417525c96658a5a35a38f5e18654176d2ce8edda 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-cache.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-cache.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Friends Caching
+ * BuddyPress Friends Caching.
  *
  * Caching functions handle the clearing of cached objects and pages on specific
  * actions throughout BuddyPress.
@@ -10,10 +10,15 @@
  * @subpackage FriendsCaching
  */
 
-
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Clear friends-related cache for members of a specific friendship.
+ *
+ * @param int $friendship_id ID of the friendship whose two members should
+ *        have their friends cache busted.
+ */
 function friends_clear_friend_object_cache( $friendship_id ) {
 	if ( !$friendship = new BP_Friends_Friendship( $friendship_id ) )
 		return false;
@@ -22,18 +27,54 @@ function friends_clear_friend_object_cache( $friendship_id ) {
 	wp_cache_delete( 'friends_friend_ids_' .    $friendship->friend_user_id,    'bp' );
 }
 
-function friends_clear_friend_notifications() {
-	global $bp;
-
-	if ( isset( $_GET['new'] ) )
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->friends->id, 'friendship_accepted' );
-}
-add_action( 'bp_activity_screen_my_activity', 'friends_clear_friend_notifications' );
-
 // List actions to clear object caches on
 add_action( 'friends_friendship_accepted', 'friends_clear_friend_object_cache' );
 add_action( 'friends_friendship_deleted',  'friends_clear_friend_object_cache' );
 
+/**
+ * Clear the friend request cache for the user not initiating the friendship.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $friend_user_id The user ID not initiating the friendship
+ */
+function bp_friends_clear_request_cache( $friend_user_id ) {
+	wp_cache_delete( $friend_user_id, 'bp_friends_requests' );
+}
+
+/**
+ * Clear the friend request cache when a friendship is saved.
+ *
+ * A friendship is deemed saved when a friendship is requested or accepted.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $friendship_id The friendship ID
+ * @param int $initiator_user_id The user ID initiating the friendship
+ * @param int $friend_user_id The user ID not initiating the friendship
+ */
+function bp_friends_clear_request_cache_on_save( $friendship_id, $initiator_user_id, $friend_user_id ) {
+	bp_friends_clear_request_cache( $friend_user_id );
+}
+add_action( 'friends_friendship_requested', 'bp_friends_clear_request_cache_on_save', 10, 3 );
+add_action( 'friends_friendship_accepted',  'bp_friends_clear_request_cache_on_save', 10, 3 );
+
+/**
+ * Clear the friend request cache when a friendship is removed.
+ *
+ * A friendship is deemed removed when a friendship is withdrawn or rejected.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $friendship_id The friendship ID
+ * @param BP_Friends_Friendship $friendship
+ */
+function bp_friends_clear_request_cache_on_remove( $friendship_id, BP_Friends_Friendship $friendship ) {
+	bp_friends_clear_request_cache( $friendship->friend_user_id );	
+}
+add_action( 'friends_friendship_withdrawn', 'bp_friends_clear_request_cache_on_remove', 10, 2 );
+add_action( 'friends_friendship_rejected',  'bp_friends_clear_request_cache_on_remove', 10, 2 );
+
 // List actions to clear super cached pages on, if super cache is installed
 add_action( 'friends_friendship_rejected',  'bp_core_clear_cache' );
 add_action( 'friends_friendship_accepted',  'bp_core_clear_cache' );
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-classes.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-classes.php
index baeb50574ad1ee283fd89066b7685213bd8a953d..63c40ca1337d81ef5329c097df334daead73f91a 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-classes.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-classes.php
@@ -1,22 +1,104 @@
 <?php
+/**
+ * BuddyPress Friends Classes
+ *
+ * @package BuddyPress
+ * @subpackage FriendsClasses
+ */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * BuddyPress Friendship object.
+ */
 class BP_Friends_Friendship {
-	var $id;
-	var $initiator_user_id;
-	var $friend_user_id;
-	var $is_confirmed;
-	var $is_limited;
-	var $date_created;
 
-	var $is_request;
-	var $populate_friend_details;
-
-	var $friend;
-
-	function __construct( $id = null, $is_request = false, $populate_friend_details = true ) {
+	/**
+	 * ID of the friendship.
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $id;
+
+	/**
+	 * User ID of the friendship initiator.
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $initiator_user_id;
+
+	/**
+	 * User ID of the 'friend' - the one invited to the friendship.
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $friend_user_id;
+
+	/**
+	 * Has the friendship been confirmed/accepted?
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $is_confirmed;
+
+	/**
+	 * Is this a "limited" friendship?
+	 *
+	 * Not currently used by BuddyPress.
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $is_limited;
+
+	/**
+	 * Date the friendship was created.
+	 *
+	 * @access public
+	 * @var string
+	 */
+	public $date_created;
+
+	/**
+	 * Is this a request?
+	 *
+	 * Not currently used in BuddyPress.
+	 *
+	 * @access public
+	 * @var unknown
+	 */
+	public $is_request;
+
+	/**
+	 * Should additional friend details be queried?
+	 *
+	 * @access public
+	 * @var bool
+	 */
+	public $populate_friend_details;
+
+	/**
+	 * Details about the friend.
+	 *
+	 * @access public
+	 * @var BP_Core_User
+	 */
+	public $friend;
+
+	/**
+	 * Constructor method.
+	 *
+	 * @param int $id Optional. The ID of an existing friendship.
+	 * @param bool $is_request Deprecated.
+	 * @param bool $populate_friend_details True if friend details should
+	 *        be queried.
+	 */
+	public function __construct( $id = null, $is_request = false, $populate_friend_details = true ) {
 		$this->is_request = $is_request;
 
 		if ( !empty( $id ) ) {
@@ -26,7 +108,10 @@ class BP_Friends_Friendship {
 		}
 	}
 
-	function populate() {
+	/**
+	 * Set up data about the current friendship.
+	 */
+	public function populate() {
 		global $wpdb, $bp;
 
 		if ( $friendship = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->friends->table_name} WHERE id = %d", $this->id ) ) ) {
@@ -46,7 +131,12 @@ class BP_Friends_Friendship {
 		}
 	}
 
-	function save() {
+	/**
+	 * Save the current friendship to the database.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function save() {
 		global $wpdb, $bp;
 
 		$this->initiator_user_id = apply_filters( 'friends_friendship_initiator_user_id_before_save', $this->initiator_user_id, $this->id );
@@ -72,15 +162,24 @@ class BP_Friends_Friendship {
 		return $result;
 	}
 
-	function delete() {
+	public function delete() {
 		global $wpdb, $bp;
-
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->friends->table_name} WHERE id = %d", $this->id ) );
 	}
 
 	/** Static Methods ********************************************************/
 
-	function get_friend_user_ids( $user_id, $friend_requests_only = false, $assoc_arr = false ) {
+	/**
+	 * Get the IDs of a given user's friends.
+	 *
+	 * @param int $user_id ID of the user whose friends are being retreived.
+	 * @param bool $friend_requests_only Optional. Whether to fetch
+	 *        unaccepted requests only. Default: false.
+	 * @param bool $assoc_arr Optional. True to receive an array of arrays
+	 *        keyed as 'user_id' => $user_id; false to get a one-dimensional
+	 *        array of user IDs. Default: false.
+	 */
+	public static function get_friend_user_ids( $user_id, $friend_requests_only = false, $assoc_arr = false ) {
 		global $wpdb, $bp;
 
 		if ( !empty( $friend_requests_only ) ) {
@@ -105,19 +204,50 @@ class BP_Friends_Friendship {
 		return $fids;
 	}
 
-	function get_friendship_id( $user_id, $friend_id ) {
+	/**
+	 * Get the ID of the friendship object, if any, between a pair of users.
+	 *
+	 * @param int $user_id The ID of the first user.
+	 * @param int $friend_id The ID of the second user.
+	 * @return int|bool The ID of the friendship object if found, otherwise
+	 *         false.
+	 */
+	public static function get_friendship_id( $user_id, $friend_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->friends->table_name} WHERE ( initiator_user_id = %d AND friend_user_id = %d ) OR ( initiator_user_id = %d AND friend_user_id = %d ) AND is_confirmed = 1", $user_id, $friend_id, $friend_id, $user_id ) );
 	}
 
-	function get_friendship_request_user_ids( $user_id ) {
-		global $wpdb, $bp;
+	/**
+	 * Get a list of IDs of users who have requested friendship of a given user.
+	 *
+	 * @param int $user_id The ID of the user who has received the
+	 *        friendship requests.
+	 * @return array|bool An array of user IDs, or false if none are found.
+	 */
+	public static function get_friendship_request_user_ids( $user_id ) {
+		$friend_requests = wp_cache_get( $user_id, 'bp_friends_requests' );
+
+		if ( false === $friend_requests ) {
+			global $wpdb, $bp;
+
+			$friend_requests = $wpdb->get_col( $wpdb->prepare( "SELECT initiator_user_id FROM {$bp->friends->table_name} WHERE friend_user_id = %d AND is_confirmed = 0", $user_id ) );
 
-		return $wpdb->get_col( $wpdb->prepare( "SELECT initiator_user_id FROM {$bp->friends->table_name} WHERE friend_user_id = %d AND is_confirmed = 0", $user_id ) );
+			wp_cache_set( $user_id, $friend_requests, 'bp_friends_requests' );
+		}
+
+		return $friend_requests;
 	}
 
-	function total_friend_count( $user_id = 0 ) {
+	/**
+	 * Get a total friend count for a given user.
+	 *
+	 * @param int $user_id Optional. ID of the user whose friendships you
+	 *        are counting. Default: displayed user (if any), otherwise
+	 *        logged-in user.
+	 * @return int Friend count for the user.
+	 */
+	public static function total_friend_count( $user_id = 0 ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -133,10 +263,26 @@ class BP_Friends_Friendship {
 			return 0;
 
 		bp_update_user_meta( $user_id, 'total_friend_count', (int) $count );
-		return (int) $count;
+
+		return absint( $count );
 	}
 
-	function search_friends( $filter, $user_id, $limit = null, $page = null ) {
+	/**
+	 * Search the friends of a user by a search string.
+	 *
+	 * @param string $filter The search string, matched against xprofile
+	 *        fields (if available), or usermeta 'nickname' field.
+	 * @param int $user_id ID of the user whose friends are being searched.
+	 * @param int $limit Optional. Max number of friends to return.
+	 * @param int $page Optional. The page of results to return. Default:
+	 *        null (no pagination - return all results).
+	 * @return array|bool On success, an array: {
+	 *     @type array $friends IDs of friends returned by the query.
+	 *     @type int $count Total number of friends (disregarding
+	 *           pagination) who match the search.
+	 * }. Returns false on failure.
+	 */
+	public static function search_friends( $filter, $user_id, $limit = null, $page = null ) {
 		global $wpdb, $bp;
 
 		// TODO: Optimize this function.
@@ -146,6 +292,7 @@ class BP_Friends_Friendship {
 
 		$filter = esc_sql( like_escape( $filter ) );
 
+		$pag_sql = '';
 		if ( !empty( $limit ) && !empty( $page ) )
 			$pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
 
@@ -176,52 +323,124 @@ class BP_Friends_Friendship {
 		return array( 'friends' => $filtered_friend_ids, 'total' => (int) $total_friend_ids );
 	}
 
-	function check_is_friend( $loggedin_userid, $possible_friend_userid ) {
+	/**
+	 * Check friendship status between two users.
+	 *
+	 * Note that 'pending' means that $initiator_userid has sent a friend
+	 * request to $possible_friend_userid that has not yet been approved,
+	 * while 'awaiting_response' is the other way around ($possible_friend_userid
+	 * sent the initial request)
+	 *
+	 * @param int $initiator_userid The ID of the user who is the initiator
+	 *        of the potential friendship/request.
+	 * @param int $possible_friend_userid The ID of the user who is the
+	 *        recipient of the potential friendship/request.
+	 * @return string The friendship status, from among 'not_friends',
+	 *        'is_friend', 'pending', and 'awaiting_response'.
+	 */
+	public static function check_is_friend( $initiator_userid, $possible_friend_userid ) {
 		global $wpdb, $bp;
 
-		if ( empty( $loggedin_userid ) || empty( $possible_friend_userid ) )
+		if ( empty( $initiator_userid ) || empty( $possible_friend_userid ) ) {
 			return false;
+		}
 
-		$result = $wpdb->get_results( $wpdb->prepare( "SELECT id, is_confirmed FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d AND friend_user_id = %d) OR (initiator_user_id = %d AND friend_user_id = %d)", $loggedin_userid, $possible_friend_userid, $possible_friend_userid, $loggedin_userid ) );
+		$result = $wpdb->get_results( $wpdb->prepare( "SELECT id, initiator_user_id, is_confirmed FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d AND friend_user_id = %d) OR (initiator_user_id = %d AND friend_user_id = %d)", $initiator_userid, $possible_friend_userid, $possible_friend_userid, $initiator_userid ) );
 
-		if ( !empty( $result ) ) {
+		if ( ! empty( $result ) ) {
 			if ( 0 == (int) $result[0]->is_confirmed ) {
-				return 'pending';
+				$status = $initiator_userid == $result[0]->initiator_user_id ? 'pending' : 'awaiting_response';
 			} else {
-				return 'is_friend';
+				$status = 'is_friend';
 			}
 		} else {
-			return 'not_friends';
+			$status = 'not_friends';
 		}
+
+		return $status;
 	}
 
-	function get_bulk_last_active( $user_ids ) {
+	/**
+	 * Get the last active date of many users at once.
+	 *
+	 * @todo Why is this in the Friends component?
+	 *
+	 * @param array $user_ids IDs of users whose last_active meta is
+	 *        being queried.
+	 * @return array Array of last_active values + user_ids.
+	 */
+	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 );
 
-		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' ) ) );
+		// 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 $retval;
 	}
 
-	function accept($friendship_id) {
+	/**
+	 * Mark a friendship as accepted.
+	 *
+	 * @param int $friendship_id ID of the friendship to be accepted.
+	 * @return int Number of database rows updated.
+	 */
+	public static function accept($friendship_id) {
 		global $wpdb, $bp;
-
 	 	return $wpdb->query( $wpdb->prepare( "UPDATE {$bp->friends->table_name} SET is_confirmed = 1, date_created = %s WHERE id = %d AND friend_user_id = %d", bp_core_current_time(), $friendship_id, bp_loggedin_user_id() ) );
 	}
 
-	function withdraw($friendship_id) {
+	/**
+	 * Remove a friendship or a friendship request INITIATED BY the logged-in user.
+	 *
+	 * @param int $friendship_id ID of the friendship to be withdrawn.
+	 * @return int Number of database rows deleted.
+	 */
+	public static function withdraw($friendship_id) {
 		global $wpdb, $bp;
-
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->friends->table_name} WHERE id = %d AND initiator_user_id = %d", $friendship_id, bp_loggedin_user_id() ) );
 	}
 
-	function reject($friendship_id) {
+	/**
+	 * Remove a friendship or a friendship request MADE OF the logged-in user.
+	 *
+	 * @param int $friendship_id ID of the friendship to be rejected.
+	 * @return int Number of database rows deleted.
+	 */
+	public static function reject($friendship_id) {
 		global $wpdb, $bp;
-
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->friends->table_name} WHERE id = %d AND friend_user_id = %d", $friendship_id, bp_loggedin_user_id() ) );
 	}
 
-	function search_users( $filter, $user_id, $limit = null, $page = null ) {
+	/**
+	 * Search users.
+	 *
+	 * @todo Why does this exist, and why is it in bp-friends?
+	 *
+	 * @param string $filter String to search by.
+	 * @param int $user_id A user ID param that is unused.
+	 * @param int $limit Optional. Max number of records to return.
+	 * @param int $page Optional. Number of the page to return. Default:
+	 *        false (no pagination - return all results).
+	 * @return array $filtered_ids IDs of users who match the query.
+	 */
+	public static function search_users( $filter, $user_id, $limit = null, $page = null ) {
 		global $wpdb, $bp;
 
 		$filter = esc_sql( like_escape( $filter ) );
@@ -229,6 +448,7 @@ class BP_Friends_Friendship {
 		$usermeta_table = $wpdb->base_prefix . 'usermeta';
 		$users_table    = $wpdb->base_prefix . 'users';
 
+		$pag_sql = '';
 		if ( !empty( $limit ) && !empty( $page ) )
 			$pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * intval( $limit ) ), intval( $limit ) );
 
@@ -247,7 +467,15 @@ class BP_Friends_Friendship {
 		return $filtered_fids;
 	}
 
-	function search_users_count( $filter ) {
+	/**
+	 * Get a count of users who match a search term.
+	 *
+	 * @todo Why does this exist, and why is it in bp-friends?
+	 *
+	 * @param string $filter Search term.
+	 * @return int Count of users matching the search term.
+	 */
+	public static function search_users_count( $filter ) {
 		global $wpdb, $bp;
 
 		$filter = esc_sql( like_escape( $filter ) );
@@ -270,7 +498,15 @@ class BP_Friends_Friendship {
 		return $user_count[0];
 	}
 
-	function sort_by_name( $user_ids ) {
+	/**
+	 * Sort a list of user IDs by their display names.
+	 *
+	 * @todo Why does this exist, and why is it in bp-friends?
+	 *
+	 * @param array $user_ids Array of user IDs.
+	 * @return array User IDs, sorted by the associated display names.
+	 */
+	public static function sort_by_name( $user_ids ) {
 		global $wpdb, $bp;
 
 		if ( !bp_is_active( 'xprofile' ) )
@@ -281,7 +517,16 @@ class BP_Friends_Friendship {
 		return $wpdb->get_results( $wpdb->prepare( "SELECT user_id FROM {$bp->profile->table_name_data} pd, {$bp->profile->table_name_fields} pf WHERE pf.id = pd.field_id AND pf.name = %s AND pd.user_id IN ( {$user_ids} ) ORDER BY pd.value ASC", bp_xprofile_fullname_field_name() ) );
 	}
 
-	function get_random_friends( $user_id, $total_friends = 5 ) {
+	/**
+	 * Get a list of random friend IDs.
+	 *
+	 * @param int $user_id ID of the user whose friends are being retrieved.
+	 * @param int $total_friends Optional. Number of random friends to get.
+	 *        Default: 5.
+	 * @return array|bool An array of random friend user IDs on success;
+	 *         false if none are found.
+	 */
+	public static function get_random_friends( $user_id, $total_friends = 5 ) {
 		global $wpdb, $bp;
 
 		$fids    = array();
@@ -299,7 +544,20 @@ class BP_Friends_Friendship {
 			return false;
 	}
 
-	function get_invitable_friend_count( $user_id, $group_id ) {
+	/**
+	 * Get a count of a user's friends who can be invited to a given group.
+	 *
+	 * Users can invite any of their friends except:
+	 *
+	 * - users who are already in the group
+	 * - users who have a pending invite to the group
+	 * - users who have been banned from the group
+	 *
+	 * @param int $user_id ID of the user whose friends are being counted.
+	 * @param int $group_id ID of the group friends are being invited to.
+	 * @return int $invitable_count Eligible friend count.
+	 */
+	public static function get_invitable_friend_count( $user_id, $group_id ) {
 
 		// Setup some data we'll use below
 		$is_group_admin  = BP_Groups_Member::check_is_admin( $user_id, $group_id );
@@ -326,13 +584,23 @@ class BP_Friends_Friendship {
 		return $invitable_count;
 	}
 
-	function get_user_ids_for_friendship( $friendship_id ) {
+	/**
+	 * Get the friend user IDs for a given friendship.
+	 *
+	 * @param int $friendship_id ID of the friendship.
+	 * @return object friend_user_id and initiator_user_id.
+	 */
+	public static function get_user_ids_for_friendship( $friendship_id ) {
 		global $wpdb, $bp;
-
 		return $wpdb->get_row( $wpdb->prepare( "SELECT friend_user_id, initiator_user_id FROM {$bp->friends->table_name} WHERE id = %d", $friendship_id ) );
 	}
 
-	function delete_all_for_user( $user_id ) {
+	/**
+	 * Delete all friendships and friend notifications related to a user.
+	 *
+	 * @param int $user_id ID of the user being expunged.
+	 */
+	public static function delete_all_for_user( $user_id ) {
 		global $wpdb, $bp;
 
 		// Get friends of $user_id
@@ -341,8 +609,11 @@ class BP_Friends_Friendship {
 		// Delete all friendships related to $user_id
 		$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->friends->table_name} WHERE friend_user_id = %d OR initiator_user_id = %d", $user_id, $user_id ) );
 
-		// Delete friend request notifications for members who have a notification from this user.
-		$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->core->table_name_notifications} WHERE component_name = 'friends' AND ( component_action = 'friendship_request' OR component_action = 'friendship_accepted' ) AND item_id = %d", $user_id ) );
+		// Delete friend request notifications for members who have a
+		// notification from this user.
+		if ( bp_is_active( 'notifications' ) ) {
+			$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->notifications->table_name} WHERE component_name = 'friends' AND ( component_action = 'friendship_request' OR component_action = 'friendship_accepted' ) AND item_id = %d", $user_id ) );
+		}
 
 		// Loop through friend_ids and update their counts
 		foreach ( (array) $friend_ids as $friend_id ) {
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-filters.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-filters.php
index 93251cb75fac59769f5b74befb683fb11d8429a5..9c66de1aae3296fb645debc2e3c5251531e46e42 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-filters.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-filters.php
@@ -8,18 +8,28 @@
  */
 
 /**
- * Filter BP_User_Query::populate_extras to override each queried users fullname
+ * Filter BP_User_Query::populate_extras to add confirmed friendship status.
  *
- * @since BuddyPress (1.7)
+ * Each member in the user query is checked for confirmed friendship status
+ * against the logged-in user.
  *
- * @global BuddyPress $bp
- * @global WPDB $wpdb
- * @param BP_User_Query $user_query
- * @param string $user_ids_sql
+ * @since BuddyPress (1.7.0)
+ *
+ * @global BuddyPress $bp Global BuddyPress settings.
+ * @global WPDB $wpdb WordPress database access object.
+ *
+ * @param BP_User_Query $user_query The BP_User_Query object.
+ * @param string $user_ids_sql Comma-separated list of user IDs to fetch extra
+ *        data for, as determined by BP_User_Query.
  */
 function bp_friends_filter_user_query_populate_extras( BP_User_Query $user_query, $user_ids_sql ) {
 	global $bp, $wpdb;
 
+	// stop if user isn't logged in
+	if ( ! is_user_logged_in() ) {
+		return;
+	}
+
 	// Fetch whether or not the user is a friend of the current user
 	$friend_status = $wpdb->get_results( $wpdb->prepare( "SELECT initiator_user_id, friend_user_id, is_confirmed FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d AND friend_user_id IN ( {$user_ids_sql} ) ) OR (initiator_user_id IN ( {$user_ids_sql} ) AND friend_user_id = %d )", bp_loggedin_user_id(), bp_loggedin_user_id() ) );
 
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-functions.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-functions.php
index eb84bdd02679fc973d86dfe267762f290423243c..67780dd313273fec8fa607cb096840ca1e80bc64 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-functions.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-functions.php
@@ -15,46 +15,73 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Create a new friendship.
+ *
+ * @param int $initiator_userid ID of the "initiator" user (the user who is
+ *        sending the friendship request).
+ * @param int $friend_userid ID of the "friend" user (the user whose friendship
+ *        is being requested).
+ * @param bool $force_accept Optional. Whether to force acceptance. When false,
+ *        running friends_add_friend() will result in a friendship request.
+ *        When true, running friends_add_friend() will result in an accepted
+ *        friendship, with no notifications being sent. Default: false.
+ * @return bool True on success, false on failure.
+ */
 function friends_add_friend( $initiator_userid, $friend_userid, $force_accept = false ) {
-	global $bp;
 
-	$friendship = new BP_Friends_Friendship;
+	// You cannot be friends with yourself!
+	if ( $initiator_userid == $friend_userid ) {
+		return false;
+	}
 
-	if ( (int) $friendship->is_confirmed )
+	// Check if already friends, and bail if so
+	if ( friends_check_friendship( $initiator_userid, $friend_userid ) ) {
 		return true;
+	}
 
+	// Setup the friendship data
+	$friendship = new BP_Friends_Friendship;
 	$friendship->initiator_user_id = $initiator_userid;
 	$friendship->friend_user_id    = $friend_userid;
 	$friendship->is_confirmed      = 0;
 	$friendship->is_limited        = 0;
 	$friendship->date_created      = bp_core_current_time();
 
-	if ( $force_accept )
+	if ( ! empty( $force_accept ) ) {
 		$friendship->is_confirmed = 1;
+	}
 
-	if ( $friendship->save() ) {
-
-		if ( !$force_accept ) {
-			// Add the on screen notification
-			bp_core_add_notification( $friendship->initiator_user_id, $friendship->friend_user_id, $bp->friends->id, 'friendship_request' );
-
-			// Send the email notification
-			friends_notification_new_request( $friendship->id, $friendship->initiator_user_id, $friendship->friend_user_id );
-
-			do_action( 'friends_friendship_requested', $friendship->id, $friendship->initiator_user_id, $friendship->friend_user_id );
-		} else {
-			// Update friend totals
-			friends_update_friend_totals( $friendship->initiator_user_id, $friendship->friend_user_id, 'add' );
+	// Bail if friendship could not be saved (how sad!)
+	if ( ! $friendship->save() ) {
+		return false;
+	}
 
-			do_action( 'friends_friendship_accepted', $friendship->id, $friendship->initiator_user_id, $friendship->friend_user_id );
-		}
+	// Send notifications
+	if ( empty( $force_accept ) ) {
+		$action = 'friends_friendship_requested';
 
-		return true;
+	// Update friend totals
+	} else {
+		$action = 'friends_friendship_accepted';
+		friends_update_friend_totals( $friendship->initiator_user_id, $friendship->friend_user_id, 'add' );
 	}
 
-	return false;
+	// Call the above titled action and pass friendship data into it
+	do_action( $action, $friendship->id, $friendship->initiator_user_id, $friendship->friend_user_id, $friendship );
+
+	return true;
 }
 
+/**
+ * Remove a friendship.
+ *
+ * Will also delete the related "friendship_accepted" activity item.
+ *
+ * @param int $initiator_userid ID of the friendship initiator.
+ * @param int $friend_userid ID of the friend user.
+ * @return bool True on success, false on failure.
+ */
 function friends_remove_friend( $initiator_userid, $friend_userid ) {
 
 	$friendship_id = BP_Friends_Friendship::get_friendship_id( $initiator_userid, $friend_userid );
@@ -80,46 +107,26 @@ function friends_remove_friend( $initiator_userid, $friend_userid ) {
 	return false;
 }
 
+/**
+ * Mark a friendship request as accepted.
+ *
+ * Also initiates a "friendship_accepted" activity item.
+ *
+ * @param int $friendship_id ID of the pending friendship object.
+ * @return bool True on success, false on failure.
+ */
 function friends_accept_friendship( $friendship_id ) {
-	global $bp;
 
+	// Get the friesdhip data
 	$friendship = new BP_Friends_Friendship( $friendship_id, true, false );
 
-	if ( !$friendship->is_confirmed && BP_Friends_Friendship::accept( $friendship_id ) ) {
-		friends_update_friend_totals( $friendship->initiator_user_id, $friendship->friend_user_id );
-
-		// Remove the friend request notice
-		bp_core_delete_notifications_by_item_id( $friendship->friend_user_id, $friendship->initiator_user_id, $bp->friends->id, 'friendship_request' );
-
-		// Add a friend accepted notice for the initiating user
-		bp_core_add_notification( $friendship->friend_user_id, $friendship->initiator_user_id, $bp->friends->id, 'friendship_accepted' );
-
-		$initiator_link = bp_core_get_userlink( $friendship->initiator_user_id );
-		$friend_link = bp_core_get_userlink( $friendship->friend_user_id );
-
-		// Record in activity streams for the initiator
-		friends_record_activity( array(
-			'user_id'           => $friendship->initiator_user_id,
-			'type'              => 'friendship_created',
-			'action'            => apply_filters( 'friends_activity_friendship_accepted_action', sprintf( __( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link ), $friendship ),
-			'item_id'           => $friendship_id,
-			'secondary_item_id' => $friendship->friend_user_id
-		) );
+	// Accepting friendship
+	if ( empty( $friendship->is_confirmed ) && BP_Friends_Friendship::accept( $friendship_id ) ) {
 
-		// Record in activity streams for the friend
-		friends_record_activity( array(
-			'user_id'           => $friendship->friend_user_id,
-			'type'              => 'friendship_created',
-			'action'            => apply_filters( 'friends_activity_friendship_accepted_action', sprintf( __( '%1$s and %2$s are now friends', 'buddypress' ), $friend_link, $initiator_link ), $friendship ),
-			'item_id'           => $friendship_id,
-			'secondary_item_id' => $friendship->initiator_user_id,
-			'hide_sitewide'     => true // We've already got the first entry site wide
-		) );
-
-		// Send the email notification
-		friends_notification_accepted_request( $friendship->id, $friendship->initiator_user_id, $friendship->friend_user_id );
+		// Bump the friendship counts
+		friends_update_friend_totals( $friendship->initiator_user_id, $friendship->friend_user_id );
 
-		do_action( 'friends_friendship_accepted', $friendship->id, $friendship->initiator_user_id, $friendship->friend_user_id );
+		do_action( 'friends_friendship_accepted', $friendship->id, $friendship->initiator_user_id, $friendship->friend_user_id, $friendship );
 
 		return true;
 	}
@@ -127,15 +134,16 @@ function friends_accept_friendship( $friendship_id ) {
 	return false;
 }
 
+/**
+ * Mark a friendship request as rejected.
+ *
+ * @param int $friendship_id ID of the pending friendship object.
+ * @return bool True on success, false on failure.
+ */
 function friends_reject_friendship( $friendship_id ) {
-	global $bp;
-
 	$friendship = new BP_Friends_Friendship( $friendship_id, true, false );
 
-	if ( !$friendship->is_confirmed && BP_Friends_Friendship::reject( $friendship_id ) ) {
-		// Remove the friend request notice
-		bp_core_delete_notifications_by_item_id( $friendship->friend_user_id, $friendship->initiator_user_id, $bp->friends->id, 'friendship_request' );
-
+	if ( empty( $friendship->is_confirmed ) && BP_Friends_Friendship::reject( $friendship_id ) ) {
 		do_action_ref_array( 'friends_friendship_rejected', array( $friendship_id, &$friendship ) );
 		return true;
 	}
@@ -143,23 +151,39 @@ function friends_reject_friendship( $friendship_id ) {
 	return false;
 }
 
+/**
+ * Withdraw a friendship request.
+ *
+ * @param int $initiator_userid ID of the friendship initiator - this is the
+ *            user who requested the friendship, and is doing the withdrawing.
+ * @param int $friend_userid ID of the requested friend.
+ * @return bool True on success, false on failure.
+ */
 function friends_withdraw_friendship( $initiator_userid, $friend_userid ) {
-	global $bp;
-
 	$friendship_id = BP_Friends_Friendship::get_friendship_id( $initiator_userid, $friend_userid );
 	$friendship    = new BP_Friends_Friendship( $friendship_id, true, false );
 
-	if ( !$friendship->is_confirmed && BP_Friends_Friendship::withdraw( $friendship_id ) ) {
-		// Remove the friend request notice
-		bp_core_delete_notifications_by_item_id( $friendship->friend_user_id, $friendship->initiator_user_id, $bp->friends->id, 'friendship_request' );
+	if ( empty( $friendship->is_confirmed ) && BP_Friends_Friendship::withdraw( $friendship_id ) ) {
 
+		// @deprecated Since 1.9
 		do_action_ref_array( 'friends_friendship_whithdrawn', array( $friendship_id, &$friendship ) );
+
+		// @since 1.9
+		do_action_ref_array( 'friends_friendship_withdrawn',  array( $friendship_id, &$friendship ) );
+
 		return true;
 	}
 
 	return false;
 }
 
+/**
+ * Check whether two users are friends.
+ *
+ * @param int $user_id ID of the first user.
+ * @param int $possible_friend_id ID of the other user.
+ * @return bool Returns true if the two users are friends, otherwise false.
+ */
 function friends_check_friendship( $user_id, $possible_friend_id ) {
 
 	if ( 'is_friend' == BP_Friends_Friendship::check_is_friend( $user_id, $possible_friend_id ) )
@@ -168,11 +192,25 @@ function friends_check_friendship( $user_id, $possible_friend_id ) {
 	return false;
 }
 
-// Returns - 'is_friend', 'not_friends', 'pending'
+/**
+ * Get the friendship status of two friends.
+ *
+ * Will return 'is_friends', 'not_friends', or 'pending'.
+ *
+ * @param int $user_id ID of the first user.
+ * @param int $possible_friend_id ID of the other user.
+ * @return string Friend status of the two users.
+ */
 function friends_check_friendship_status( $user_id, $possible_friend_id ) {
 	return BP_Friends_Friendship::check_is_friend( $user_id, $possible_friend_id );
 }
 
+/**
+ * Get the friend count of a given user.
+ *
+ * @param int $user_id ID of the user whose friends are being counted.
+ * @return int Friend count of the user.
+ */
 function friends_get_total_friend_count( $user_id = 0 ) {
 	if ( empty( $user_id ) )
 		$user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
@@ -184,6 +222,12 @@ function friends_get_total_friend_count( $user_id = 0 ) {
 	return apply_filters( 'friends_get_total_friend_count', $count );
 }
 
+/**
+ * Check whether a given user has any friends.
+ *
+ * @param int $user_id ID of the user whose friends are being checked.
+ * @return bool True if the user has friends, otherwise false.
+ */
 function friends_check_user_has_friends( $user_id ) {
 	$friend_count = friends_get_total_friend_count( $user_id );
 
@@ -196,34 +240,124 @@ function friends_check_user_has_friends( $user_id ) {
 	return true;
 }
 
+/**
+ * Get the ID of two users' friendship, if it exists.
+ *
+ * @param int $initiator_user_id ID of the first user.
+ * @param int $friend_user_id ID of the second user.
+ * @return int|bool ID of the friendship if found, otherwise false.
+ */
 function friends_get_friendship_id( $initiator_user_id, $friend_user_id ) {
 	return BP_Friends_Friendship::get_friendship_id( $initiator_user_id, $friend_user_id );
 }
 
+/**
+ * Get the IDs of a given user's friends.
+ *
+ * @param int $user_id ID of the user whose friends are being retreived.
+ * @param bool $friend_requests_only Optional. Whether to fetch unaccepted
+ *        requests only. Default: false.
+ * @param bool $assoc_arr Optional. True to receive an array of arrays keyed as
+ *        'user_id' => $user_id; false to get a one-dimensional array of user
+ *        IDs. Default: false.
+ */
 function friends_get_friend_user_ids( $user_id, $friend_requests_only = false, $assoc_arr = false ) {
 	return BP_Friends_Friendship::get_friend_user_ids( $user_id, $friend_requests_only, $assoc_arr );
 }
 
+/**
+ * Search the friends of a user by a search string.
+ *
+ * @param string $filter The search string, matched against xprofile fields (if
+ *        available), or usermeta 'nickname' field.
+ * @param int $user_id ID of the user whose friends are being searched.
+ * @param int $limit Optional. Max number of friends to return.
+ * @param int $page Optional. The page of results to return. Default: null (no
+ *        pagination - return all results).
+ * @return array|bool On success, an array: {
+ *     @type array $friends IDs of friends returned by the query.
+ *     @type int $count Total number of friends (disregarding
+ *           pagination) who match the search.
+ * }. Returns false on failure.
+ */
 function friends_search_friends( $search_terms, $user_id, $pag_num = 10, $pag_page = 1 ) {
 	return BP_Friends_Friendship::search_friends( $search_terms, $user_id, $pag_num, $pag_page );
 }
 
+/**
+ * Get a list of IDs of users who have requested friendship of a given user.
+ *
+ * @param int $user_id The ID of the user who has received the friendship
+ *        requests.
+ * @return array|bool An array of user IDs, or false if none are found.
+ */
 function friends_get_friendship_request_user_ids( $user_id ) {
 	return BP_Friends_Friendship::get_friendship_request_user_ids( $user_id );
 }
 
+/**
+ * Get a user's most recently active friends.
+ *
+ * @see BP_Core_User::get_users() for a description of return value.
+ *
+ * @param int $user_id ID of the user whose friends are being retreived.
+ * @param int $per_page Optional. Number of results to return per page.
+ *        Default: 0 (no pagination; show all results).
+ * @param int $page Optional. Number of the page of results to return.
+ *        Default: 0 (no pagination; show all results).
+ * @param string $filter Optional. Limit results to those matching a search
+ *        string.
+ * @return array See {@link BP_Core_User::get_users()}.
+ */
 function friends_get_recently_active( $user_id, $per_page = 0, $page = 0, $filter = '' ) {
 	return apply_filters( 'friends_get_recently_active', BP_Core_User::get_users( 'active', $per_page, $page, $user_id, $filter ) );
 }
 
+/**
+ * Get a user's friends, in alphabetical order.
+ *
+ * @see BP_Core_User::get_users() for a description of return value.
+ *
+ * @param int $user_id ID of the user whose friends are being retreived.
+ * @param int $per_page Optional. Number of results to return per page.
+ *        Default: 0 (no pagination; show all results).
+ * @param int $page Optional. Number of the page of results to return.
+ *        Default: 0 (no pagination; show all results).
+ * @param string $filter Optional. Limit results to those matching a search
+ *        string.
+ * @return array See {@link BP_Core_User::get_users()}.
+ */
 function friends_get_alphabetically( $user_id, $per_page = 0, $page = 0, $filter = '' ) {
 	return apply_filters( 'friends_get_alphabetically', BP_Core_User::get_users( 'alphabetical', $per_page, $page, $user_id, $filter ) );
 }
 
+/**
+ * Get a user's friends, in the order in which they joined the site.
+ *
+ * @see BP_Core_User::get_users() for a description of return value.
+ *
+ * @param int $user_id ID of the user whose friends are being retreived.
+ * @param int $per_page Optional. Number of results to return per page.
+ *        Default: 0 (no pagination; show all results).
+ * @param int $page Optional. Number of the page of results to return.
+ *        Default: 0 (no pagination; show all results).
+ * @param string $filter Optional. Limit results to those matching a search
+ *        string.
+ * @return array See {@link BP_Core_User::get_users()}.
+ */
 function friends_get_newest( $user_id, $per_page = 0, $page = 0, $filter = '' ) {
 	return apply_filters( 'friends_get_newest', BP_Core_User::get_users( 'newest', $per_page, $page, $user_id, $filter ) );
 }
 
+/**
+ * Get the last active date of many users at once.
+ *
+ * @see BP_Friends_Friendship::get_bulk_last_active() for a description of
+ *      arguments and return value.
+ *
+ * @param array $user_ids See BP_Friends_Friendship::get_bulk_last_active().
+ * @return array $user_ids See BP_Friends_Friendship::get_bulk_last_active().
+ */
 function friends_get_bulk_last_active( $friend_ids ) {
 	return BP_Friends_Friendship::get_bulk_last_active( $friend_ids );
 }
@@ -234,10 +368,12 @@ function friends_get_bulk_last_active( $friend_ids ) {
  * Excludes friends that are already in the group, and banned friends if the
  * user is not a group admin.
  *
- * @since BuddyPress (1.0)
- * @param int $user_id User ID whose friends to see can be invited
- * @param int $group_id Group to check possible invitations against
- * @return mixed False if no friends, array of users if friends
+ * @since BuddyPress (1.0.0)
+ *
+ * @param int $user_id User ID whose friends to see can be invited. Default:
+ *        ID of the logged-in user.
+ * @param int $group_id Group to check possible invitations against.
+ * @return mixed False if no friends, array of users if friends.
  */
 function friends_get_friends_invite_list( $user_id = 0, $group_id = 0 ) {
 
@@ -302,14 +438,45 @@ function friends_get_friends_invite_list( $user_id = 0, $group_id = 0 ) {
 	return apply_filters( 'bp_friends_get_invite_list', $friends, $user_id, $group_id );
 }
 
+/**
+ * Get a count of a user's friends who can be invited to a given group.
+ *
+ * Users can invite any of their friends except:
+ *
+ * - users who are already in the group
+ * - users who have a pending invite to the group
+ * - users who have been banned from the group
+ *
+ * @param int $user_id ID of the user whose friends are being counted.
+ * @param int $group_id ID of the group friends are being invited to.
+ * @return int $invitable_count Eligible friend count.
+ */
 function friends_count_invitable_friends( $user_id, $group_id ) {
 	return BP_Friends_Friendship::get_invitable_friend_count( $user_id, $group_id );
 }
 
+/**
+ * Get a total friend count for a given user.
+ *
+ * @param int $user_id Optional. ID of the user whose friendships you are
+ *        counting. Default: displayed user (if any), otherwise logged-in user.
+ * @return int Friend count for the user.
+ */
 function friends_get_friend_count_for_user( $user_id ) {
 	return BP_Friends_Friendship::total_friend_count( $user_id );
 }
 
+/**
+ * Return a list of a user's friends, filtered by a search term.
+ *
+ * @param string $search_terms Search term to filter on.
+ * @param int $user_id ID of the user whose friends are being searched.
+ * @param int $pag_num Number of results to return per page. Default: 0 (no
+ *        pagination - show all results).
+ * @param int $pag_num Number of the page being requested. Default: 0 (no
+ *        pagination - show all results).
+ * @return array Array of BP_Core_User objects corresponding to friends.
+ */
 function friends_search_users( $search_terms, $user_id, $pag_num = 0, $pag_page = 0 ) {
 
 	$user_ids = BP_Friends_Friendship::search_users( $search_terms, $user_id, $pag_num, $pag_page );
@@ -324,11 +491,30 @@ function friends_search_users( $search_terms, $user_id, $pag_num = 0, $pag_page
 	return array( 'users' => $users, 'count' => BP_Friends_Friendship::search_users_count( $search_terms ) );
 }
 
+/**
+ * Has a friendship been confirmed (accepted)?
+ *
+ * @param int $friendship_id The ID of the friendship being checked.
+ * @return bool True if the friendship is confirmed, otherwise false.
+ */
 function friends_is_friendship_confirmed( $friendship_id ) {
 	$friendship = new BP_Friends_Friendship( $friendship_id );
 	return $friendship->is_confirmed;
 }
 
+/**
+ * Update user friend counts.
+ *
+ * Friend counts are cached in usermeta for performance reasons. After a
+ * friendship event (acceptance, deletion), call this function to regenerate
+ * the cached values.
+ *
+ * @param int $initiator_user_id ID of the first user.
+ * @param int $friend_user_id ID of the second user.
+ * @param string $status Optional. The friendship event that's been triggered.
+ *        'add' will ++ each user's friend counts, while any other string
+ *        will --.
+ */
 function friends_update_friend_totals( $initiator_user_id, $friend_user_id, $status = 'add' ) {
 
 	if ( 'add' == $status ) {
@@ -340,8 +526,18 @@ function friends_update_friend_totals( $initiator_user_id, $friend_user_id, $sta
 	}
 }
 
+/**
+ * Remove all friends-related data concerning a given user.
+ *
+ * Removes the following:
+ *
+ * - Friendships of which the user is a member
+ * - Cached friend count for the user
+ * - Notifications of friendship requests sent by the user
+ *
+ * @param int $user_id ID of the user whose friend data is being removed.
+ */
 function friends_remove_data( $user_id ) {
-	global $bp;
 
 	do_action( 'friends_before_remove_data', $user_id );
 
@@ -350,9 +546,6 @@ function friends_remove_data( $user_id ) {
 	// Remove usermeta
 	bp_delete_user_meta( $user_id, 'total_friend_count' );
 
-	// Remove friendship requests FROM user
-	bp_core_delete_notifications_from_user( $user_id, $bp->friends->id, 'friendship_request' );
-
 	do_action( 'friends_remove_data', $user_id );
 }
 add_action( 'wpmu_delete_user',  'friends_remove_data' );
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-loader.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-loader.php
index 3ff1e0b4cecf9238ad3efb612a5eba05e4857e8f..3545bfcc6b439b901d71eb5f215acf409d2d0235 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-loader.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-loader.php
@@ -2,10 +2,10 @@
 /**
  * BuddyPress Friends Streams Loader
  *
- * The friends component is for users to create relationships with each other
+ * The friends component is for users to create relationships with each other.
  *
  * @package BuddyPress
- * @subpackage Friends Core
+ * @subpackage Friends
  */
 
 // Exit if accessed directly
@@ -14,24 +14,31 @@ if ( !defined( 'ABSPATH' ) ) exit;
 class BP_Friends_Component extends BP_Component {
 
 	/**
-	 * Start the friends component creation process
+	 * Start the friends component creation process.
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'friends',
 			__( 'Friend Connections', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 60
+			)
 		);
 	}
 
 	/**
-	 * Include files
+	 * Include bp-friends files.
+	 *
+	 * @see BP_Component::includes() for description of parameters.
+	 *
+	 * @param array $includes See {@link BP_Component::includes()}.
 	 */
 	public function includes( $includes = array() ) {
-		// Files to include
 		$includes = array(
+			'cache',
 			'actions',
 			'screens',
 			'filters',
@@ -40,24 +47,32 @@ class BP_Friends_Component extends BP_Component {
 			'template',
 			'functions',
 			'notifications',
+			'widgets',
 		);
 
 		parent::includes( $includes );
 	}
 
 	/**
-	 * Setup globals
+	 * Set up bp-friends global settings.
 	 *
 	 * The BP_FRIENDS_SLUG constant is deprecated, and only used here for
 	 * backwards compatibility.
 	 *
-	 * @since BuddyPress (1.5)
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @see BP_Component::setup_globals() for description of parameters.
+	 *
+	 * @param array $args See {@link BP_Component::setup_globals()}.
 	 */
 	public function setup_globals( $args = array() ) {
-		global $bp;
+		$bp = buddypress();
 
-		define ( 'BP_FRIENDS_DB_VERSION', '1800' );
+		// Deprecated. Do not use.
+		// Defined conditionally to support unit tests.
+		if ( ! defined( 'BP_FRIENDS_DB_VERSION' ) ) {
+			define( 'BP_FRIENDS_DB_VERSION', '1800' );
+		}
 
 		// Define a slug, if necessary
 		if ( !defined( 'BP_FRIENDS_SLUG' ) )
@@ -71,7 +86,7 @@ class BP_Friends_Component extends BP_Component {
 
 		// All globals for the friends component.
 		// Note that global_tables is included in this array.
-		$globals = array(
+		$args = array(
 			'slug'                  => BP_FRIENDS_SLUG,
 			'has_directory'         => false,
 			'search_string'         => __( 'Search Friends...', 'buddypress' ),
@@ -79,22 +94,29 @@ class BP_Friends_Component extends BP_Component {
 			'global_tables'         => $global_tables
 		);
 
-		parent::setup_globals( $globals );
+		parent::setup_globals( $args );
 	}
 
 	/**
-	 * Setup BuddyBar navigation
+	 * Set up component navigation.
+	 *
+	 * @since BuddyPress (1.5.0)
+	 *
+	 * @see BP_Component::setup_nav() for a description of arguments.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * @param array $main_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
+	 * @param array $sub_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
-		global $bp;
-
-		$sub_nav = array();
+		$bp = buddypress();
 
 		// Add 'Friends' to the main navigation
+		$count    = friends_get_total_friend_count();
+		$class    = ( 0 === $count ) ? 'no-count' : 'count';
 		$main_nav = array(
-			'name'                => sprintf( __( 'Friends <span>%d</span>', 'buddypress' ), friends_get_total_friend_count() ),
+			'name'                => sprintf( __( 'Friends <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), number_format_i18n( $count ) ),
 			'slug'                => $this->slug,
 			'position'            => 60,
 			'screen_function'     => 'friends_screen_my_friends',
@@ -138,15 +160,17 @@ class BP_Friends_Component extends BP_Component {
 	}
 
 	/**
-	 * Set up the Toolbar
+	 * Set up bp-friends integration with the WordPress admin bar.
+	 *
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * @see BP_Component::setup_admin_bar() for a description of arguments.
+	 *
+	 * @param array $wp_admin_nav See BP_Component::setup_admin_bar()
+	 *        for description.
 	 */
 	public function setup_admin_bar( $wp_admin_nav = array() ) {
-		global $bp;
-
-		// Prevent debug notices
-		$wp_admin_nav = array();
+		$bp = buddypress();
 
 		// Menus for logged in user
 		if ( is_user_logged_in() ) {
@@ -194,12 +218,10 @@ class BP_Friends_Component extends BP_Component {
 	}
 
 	/**
-	 * Sets up the title for pages and <title>
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * Set up the title for pages and <title>.
 	 */
-	function setup_title() {
-		global $bp;
+	public function setup_title() {
+		$bp = buddypress();
 
 		// Adjust title
 		if ( bp_is_friends_component() ) {
@@ -219,8 +241,10 @@ class BP_Friends_Component extends BP_Component {
 	}
 }
 
+/**
+ * Set up the bp-forums component.
+ */
 function bp_setup_friends() {
-	global $bp;
-	$bp->friends = new BP_Friends_Component();
+	buddypress()->friends = new BP_Friends_Component();
 }
 add_action( 'bp_setup_components', 'bp_setup_friends', 6 );
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-notifications.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-notifications.php
index c38b0274e75a7325f2f2fc366b638d9afb53e21f..4fb805ba91905cb841c27a34e5aac0af8b0f3f07 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-notifications.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-notifications.php
@@ -13,6 +13,18 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/** Emails ********************************************************************/
+
+/**
+ * Send notifications related to a new friendship request.
+ *
+ * When a friendship is requested, an email and a BP notification are sent to
+ * the user of whom friendship has been requested ($friend_id).
+ *
+ * @param int $friendship_id ID of the friendship object.
+ * @param int $initiator_id ID of the user who initiated the request.
+ * @param int $friend_id ID of the request recipient.
+ */
 function friends_notification_new_request( $friendship_id, $initiator_id, $friend_id ) {
 
 	$initiator_name = bp_core_get_user_displayname( $initiator_id );
@@ -44,8 +56,8 @@ To view %3$s\'s profile: %4$s
 		$message .= sprintf( __( 'To disable these notifications please log in and go to: %s', 'buddypress' ), $settings_link );
 	}
 
-	/* Send the message */
-	$to = apply_filters( 'friends_notification_new_request_to', $to );
+	// Send the message
+	$to      = apply_filters( 'friends_notification_new_request_to', $to );
 	$subject = apply_filters( 'friends_notification_new_request_subject', $subject, $initiator_name );
 	$message = apply_filters( 'friends_notification_new_request_message', $message, $initiator_name, $initiator_link, $all_requests_link, $settings_link );
 
@@ -53,7 +65,18 @@ To view %3$s\'s profile: %4$s
 
 	do_action( 'bp_friends_sent_request_email', $friend_id, $subject, $message, $friendship_id, $initiator_id );
 }
+add_action( 'friends_friendship_requested', 'friends_notification_new_request', 10, 3 );
 
+/**
+ * Send notifications related to the acceptance of a friendship request.
+ *
+ * When a friendship request is accepted, an email and a BP notification are
+ * sent to the user who requested the friendship ($initiator_id).
+ *
+ * @param int $friendship_id ID of the friendship object.
+ * @param int $initiator_id ID of the user who initiated the request.
+ * @param int $friend_id ID of the request recipient.
+ */
 function friends_notification_accepted_request( $friendship_id, $initiator_id, $friend_id ) {
 
 	$friend_name = bp_core_get_user_displayname( $friend_id );
@@ -82,8 +105,8 @@ To view %2$s\'s profile: %3$s
 		$message .= sprintf( __( 'To disable these notifications please log in and go to: %s', 'buddypress' ), $settings_link );
 	}
 
-	/* Send the message */
-	$to = apply_filters( 'friends_notification_accepted_request_to', $to );
+	// Send the message
+	$to      = apply_filters( 'friends_notification_accepted_request_to', $to );
 	$subject = apply_filters( 'friends_notification_accepted_request_subject', $subject, $friend_name );
 	$message = apply_filters( 'friends_notification_accepted_request_message', $message, $friend_name, $friend_link, $settings_link );
 
@@ -91,3 +114,196 @@ To view %2$s\'s profile: %3$s
 
 	do_action( 'bp_friends_sent_accepted_email', $initiator_id, $subject, $message, $friendship_id, $friend_id );
 }
+add_action( 'friends_friendship_accepted', 'friends_notification_accepted_request', 10, 3 );
+
+/** Notifications *************************************************************/
+
+/**
+ * Notification formatting callback for bp-friends notifications.
+ *
+ * @param string $action The kind of notification being rendered.
+ * @param int $item_id The primary item ID.
+ * @param int $secondary_item_id The secondary item ID.
+ * @param int $total_items The total number of messaging-related notifications
+ *        waiting for the user.
+ * @param string $format 'string' for BuddyBar-compatible notifications;
+ *        'array' for WP Toolbar. Default: 'string'.
+ * @return array|string
+ */
+function friends_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
+
+	switch ( $action ) {
+		case 'friendship_accepted':
+			$link = trailingslashit( bp_loggedin_user_domain() . bp_get_friends_slug() . '/my-friends' );
+
+			// Set up the string and the filter
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( '%d friends accepted your friendship requests', 'buddypress' ), (int) $total_items );
+				$filter = 'bp_friends_multiple_friendship_accepted_notification';
+			} else {
+				$text = sprintf( __( '%s accepted your friendship request', 'buddypress' ),  bp_core_get_user_displayname( $item_id ) );
+				$filter = 'bp_friends_single_friendship_accepted_notification';
+			}
+
+			break;
+
+		case 'friendship_request':
+			$link = bp_loggedin_user_domain() . bp_get_friends_slug() . '/requests/?new';
+
+			// Set up the string and the filter
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( 'You have %d pending friendship requests', 'buddypress' ), (int) $total_items );
+				$filter = 'bp_friends_multiple_friendship_request_notification';
+			} else {
+				$text = sprintf( __( 'You have a friendship request from %s', 'buddypress' ),  bp_core_get_user_displayname( $item_id ) );
+				$filter = 'bp_friends_single_friendship_request_notification';
+			}
+
+			break;
+	}
+
+	// Return either an HTML link or an array, depending on the requested format
+	if ( 'string' == $format ) {
+		$return = apply_filters( $filter, '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>', (int) $total_items, $item_id );
+	} else {
+		$return = apply_filters( $filter, array(
+			'link' => $link,
+			'text' => $text
+		), (int) $total_items, $item_id );
+	}
+
+	do_action( 'friends_format_notifications', $action, $item_id, $secondary_item_id, $total_items, $return );
+
+	return $return;
+}
+
+/**
+ * Clear friend-related notifications when ?new=1
+ */
+function friends_clear_friend_notifications() {
+	if ( isset( $_GET['new'] ) && bp_is_active( 'notifications' ) ) {
+		bp_notifications_mark_notifications_by_type( bp_loggedin_user_id(), buddypress()->friends->id, 'friendship_accepted' );
+	}
+}
+add_action( 'bp_activity_screen_my_activity', 'friends_clear_friend_notifications' );
+
+/**
+ * Delete any friendship request notifications for the logged in user.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_friends_mark_friendship_request_notifications_by_type() {
+	if ( isset( $_GET['new'] ) && bp_is_active( 'notifications' ) ) {
+		bp_notifications_mark_notifications_by_type( bp_loggedin_user_id(), buddypress()->friends->id, 'friendship_request' );
+	}
+}
+add_action( 'friends_screen_requests', 'bp_friends_mark_friendship_request_notifications_by_type' );
+
+/**
+ * Delete any friendship acceptance notifications for the logged in user.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_friends_mark_friendship_accepted_notifications_by_type() {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_mark_notifications_by_type( bp_loggedin_user_id(), buddypress()->friends->id, 'friendship_accepted' );
+	}
+}
+add_action( 'friends_screen_my_friends', 'bp_friends_mark_friendship_accepted_notifications_by_type' );
+
+/**
+ * Notify one use that another user has requested their virtual friendship.
+ *
+ * @since BuddyPress (1.9.0)
+ * @param int $friendship_id The unique ID of the friendship
+ * @param int $initiator_user_id The friendship initiator user ID
+ * @param int $friend_user_id The friendship request reciever user ID
+ */
+function bp_friends_friendship_requested_notification( $friendship_id, $initiator_user_id, $friend_user_id ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_add_notification( array(
+			'user_id'           => $friend_user_id,
+			'item_id'           => $initiator_user_id,
+			'secondary_item_id' => $friendship_id,
+			'component_name'    => buddypress()->friends->id,
+			'component_action'  => 'friendship_request',
+			'date_notified'     => bp_core_current_time(),
+			'is_new'            => 1,
+		) );
+	}
+}
+add_action( 'friends_friendship_requested', 'bp_friends_friendship_requested_notification', 10, 3 );
+
+/**
+ * Remove friend request notice when a member rejects another members
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $friendship_id (not used)
+ * @param object $friendship
+ */
+function bp_friends_mark_friendship_rejected_notifications_by_item_id( $friendship_id, $friendship ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_mark_notifications_by_item_id( $friendship->friend_user_id, $friendship->initiator_user_id, buddypress()->friends->id, 'friendship_request' );
+	}
+}
+add_action( 'friends_friendship_rejected', 'bp_friends_mark_friendship_rejected_notifications_by_item_id', 10, 2 );
+
+/**
+ * Notify a member when another member accepts their virtual friendship request.
+ *
+ * @since BuddyPress (1.9.0)
+ * @param int $friendship_id The unique ID of the friendship
+ * @param int $initiator_user_id The friendship initiator user ID
+ * @param int $friend_user_id The friendship request reciever user ID
+ */
+function bp_friends_add_friendship_accepted_notification( $friendship_id, $initiator_user_id, $friend_user_id ) {
+
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return;
+	}
+
+	// Remove the friend request notice
+	bp_notifications_mark_notifications_by_item_id( $friend_user_id, $initiator_user_id, buddypress()->friends->id, 'friendship_request' );
+
+	// Add a friend accepted notice for the initiating user
+	bp_notifications_add_notification(  array(
+		'user_id'           => $initiator_user_id,
+		'item_id'           => $friend_user_id,
+		'secondary_item_id' => $friendship_id,
+		'component_name'    => buddypress()->friends->id,
+		'component_action'  => 'friendship_accepted',
+		'date_notified'     => bp_core_current_time(),
+		'is_new'            => 1,
+	) );
+}
+add_action( 'friends_friendship_accepted', 'bp_friends_add_friendship_accepted_notification', 10, 3 );
+
+/**
+ * Remove friend request notice when a member withdraws their friend request
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $friendship_id (not used)
+ * @param object $friendship
+ */
+function bp_friends_mark_friendship_withdrawn_notifications_by_item_id( $friendship_id, $friendship ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_delete_notifications_by_item_id( $friendship->friend_user_id, $friendship->initiator_user_id, buddypress()->friends->id, 'friendship_request' );
+	}
+}
+add_action( 'friends_friendship_withdrawn', 'bp_friends_mark_friendship_withdrawn_notifications_by_item_id', 10, 2 );
+
+/**
+ * Remove friendship requests FROM user, used primarily when a user is deleted
+ *
+ * @since BuddyPress (1.9.0)
+ * @param int $user_id
+ */
+function bp_friends_remove_notifications_data( $user_id = 0 ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_delete_notifications_from_user( $user_id, buddypress()->friends->id, 'friendship_request' );
+	}
+}
+add_action( 'friends_remove_data', 'bp_friends_remove_notifications_data', 10, 1 );
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-screens.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-screens.php
index 9dba23b7745a737aae499eb36ff945f1895ae212..9beddd3251be974ae367dffeb2830bfc2da485e0 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-screens.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-screens.php
@@ -3,9 +3,9 @@
 /**
  * BuddyPress Friends Screen Functions
  *
- * Screen functions are the controllers of BuddyPress. They will execute when their
- * specific URL is caught. They will first save or manipulate data using business
- * functions, then pass on the user to a template file.
+ * Screen functions are the controllers of BuddyPress. They will execute when
+ * their specific URL is caught. They will first save or manipulate data using
+ * business functions, then pass on the user to a template file.
  *
  * @package BuddyPress
  * @subpackage FriendsScreens
@@ -14,17 +14,19 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Catch and process the My Friends page.
+ */
 function friends_screen_my_friends() {
-	global $bp;
-
-	// Delete any friendship acceptance notifications for the user when viewing a profile
-	bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->friends->id, 'friendship_accepted' );
 
 	do_action( 'friends_screen_my_friends' );
 
 	bp_core_load_template( apply_filters( 'friends_template_my_friends', 'members/single/home' ) );
 }
 
+/**
+ * Catch and process the Requests page.
+ */
 function friends_screen_requests() {
 	if ( bp_is_action_variable( 'accept', 0 ) && is_numeric( bp_action_variable( 1 ) ) ) {
 		// Check the nonce
@@ -62,12 +64,12 @@ function friends_screen_requests() {
 
 	do_action( 'friends_screen_requests' );
 
-	if ( isset( $_GET['new'] ) )
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), 'friends', 'friendship_request' );
-
 	bp_core_load_template( apply_filters( 'friends_template_requests', 'members/single/home' ) );
 }
 
+/**
+ * Add Friends-related settings to the Settings > Notifications page.
+ */
 function friends_screen_notification_settings() {
 
 	if ( !$send_requests = bp_get_user_meta( bp_displayed_user_id(), 'notification_friends_friendship_request', true ) )
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-template.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-template.php
index 921c12160185900d21a03617b76dd9e4681cb67c..5d41c7846d3a3033c326a5d309996a3fb09a2062 100644
--- a/wp-content/plugins/buddypress/bp-friends/bp-friends-template.php
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-template.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * BuddyPress Friends Template Functions
+ * BuddyPress Friends Template Functions.
  *
  * @package BuddyPress
  * @subpackage FriendsTemplate
@@ -11,11 +11,9 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Output the friends component slug
+ * Output the friends component slug.
  *
- * @package BuddyPress
- * @subpackage Friends Template
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_friends_slug()
  */
@@ -23,23 +21,18 @@ function bp_friends_slug() {
 	echo bp_get_friends_slug();
 }
 	/**
-	 * Return the friends component slug
+	 * Return the friends component slug.
 	 *
-	 * @package BuddyPress
-	 * @subpackage Friends Template
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 */
 	function bp_get_friends_slug() {
-		global $bp;
-		return apply_filters( 'bp_get_friends_slug', $bp->friends->slug );
+		return apply_filters( 'bp_get_friends_slug', buddypress()->friends->slug );
 	}
 
 /**
- * Output the friends component root slug
+ * Output the friends component root slug.
  *
- * @package BuddyPress
- * @subpackage Friends Template
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
  * @uses bp_get_friends_root_slug()
  */
@@ -47,17 +40,21 @@ function bp_friends_root_slug() {
 	echo bp_get_friends_root_slug();
 }
 	/**
-	 * Return the friends component root slug
+	 * Return the friends component root slug.
 	 *
-	 * @package BuddyPress
-	 * @subpackage Friends Template
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 */
 	function bp_get_friends_root_slug() {
-		global $bp;
-		return apply_filters( 'bp_get_friends_root_slug', $bp->friends->root_slug );
+		return apply_filters( 'bp_get_friends_root_slug', buddypress()->friends->root_slug );
 	}
 
+/**
+ * Output a block of random friends.
+ *
+ * No longer used in BuddyPress.
+ *
+ * @todo Deprecate
+ */
 function bp_friends_random_friends() {
 
 	if ( !$friend_ids = wp_cache_get( 'friends_friend_ids_' . bp_displayed_user_id(), 'bp' ) ) {
@@ -98,13 +95,13 @@ function bp_friends_random_friends() {
 }
 
 /**
- * Pull up a group of random members, and display some profile data about them
+ * Pull up a group of random members, and display some profile data about them.
  *
  * This function is no longer used by BuddyPress core.
  *
- * @package BuddyPress
+ * @todo Deprecate
  *
- * @param int $total_members The number of members to retrieve
+ * @param int $total_members The number of members to retrieve.
  */
 function bp_friends_random_members( $total_members = 5 ) {
 
@@ -163,6 +160,13 @@ function bp_friends_random_members( $total_members = 5 ) {
 <?php
 }
 
+/**
+ * Display a Friends search form.
+ *
+ * No longer used in BuddyPress.
+ *
+ * @todo Deprecate
+ */
 function bp_friend_search_form() {
 
 	$action = bp_displayed_user_domain() . bp_get_friends_slug() . '/my-friends/search/';
@@ -182,6 +186,9 @@ function bp_friend_search_form() {
 	<?php
 }
 
+/**
+ * Output the Add Friend button in member directories.
+ */
 function bp_member_add_friend_button() {
 	global $members_template;
 
@@ -194,9 +201,19 @@ function bp_member_add_friend_button() {
 }
 add_action( 'bp_directory_members_actions', 'bp_member_add_friend_button' );
 
+/**
+ * Output the friend count for the current member in the loop.
+ */
 function bp_member_total_friend_count() {
 	echo bp_get_member_total_friend_count();
 }
+	/**
+	 * Return the friend count for the current member in the loop.
+	 *
+	 * Return value is a string of the form "x friends".
+	 *
+	 * @return string A string of the form "x friends".
+	 */
 	function bp_get_member_total_friend_count() {
 		global $members_template;
 
@@ -207,24 +224,23 @@ function bp_member_total_friend_count() {
 	}
 
 /**
- * bp_potential_friend_id( $user_id )
+ * Output the ID of the current user in the friend request loop.
  *
- * Outputs the ID of the potential friend
+ * @see bp_get_potential_friend_id() for a description of arguments.
  *
- * @uses bp_get_potential_friend_id()
- * @param int $user_id Optional
+ * @param int $user_id See {@link bp_get_potential_friend_id()}.
  */
 function bp_potential_friend_id( $user_id = 0 ) {
 	echo bp_get_potential_friend_id( $user_id );
 }
 	/**
-	 * bp_get_potential_friend_id( $user_id )
-	 *
-	 * Returns the ID of the potential friend
+	 * Return the ID of current user in the friend request loop.
 	 *
 	 * @global object $friends_template
-	 * @param int $user_id
-	 * @return int ID of potential friend
+	 *
+	 * @param int $user_id Optional. If provided, the function will simply
+	 *        return this value.
+	 * @return int ID of potential friend.
 	 */
 	function bp_get_potential_friend_id( $user_id = 0 ) {
 		global $friends_template;
@@ -238,12 +254,13 @@ function bp_potential_friend_id( $user_id = 0 ) {
 	}
 
 /**
- * bp_is_friend( $user_id )
+ * Check whether a given user is a friend of the logged-in user.
  *
- * Returns - 'is_friend', 'not_friends', 'pending'
+ * Returns - 'is_friend', 'not_friends', 'pending'.
  *
- * @param int $potential_friend_id
- * @return string
+ * @param int $user_id ID of the potential friend. Default: the value of
+ *        {@link bp_get_potential_friend_id()}.
+ * @return string 'is_friend', 'not_friends', or 'pending'.
  */
 function bp_is_friend( $user_id = 0 ) {
 
@@ -259,9 +276,25 @@ function bp_is_friend( $user_id = 0 ) {
 	return apply_filters( 'bp_is_friend', friends_check_friendship_status( bp_loggedin_user_id(), $user_id ), $user_id );
 }
 
+/**
+ * Output the Add Friend button.
+ *
+ * @see bp_get_add_friend_button() for information on arguments.
+ *
+ * @param int $potential_friend_id See {@link bp_get_add_friend_button()}.
+ * @param int $friend_status See {@link bp_get_add_friend_button()}.
+ */
 function bp_add_friend_button( $potential_friend_id = 0, $friend_status = false ) {
 	echo bp_get_add_friend_button( $potential_friend_id, $friend_status );
 }
+	/**
+	 * Create the Add Friend button.
+	 *
+	 * @param int $potential_friend_id ID of the user to whom the button
+	 *        applies. Default: value of {@link bp_get_potential_friend_id()}.
+	 * @param bool $friend_status Not currently used.
+	 * @return string HTML for the Add Friend button.
+	 */
 	function bp_get_add_friend_button( $potential_friend_id = 0, $friend_status = false ) {
 
 		if ( empty( $potential_friend_id ) )
@@ -290,6 +323,23 @@ function bp_add_friend_button( $potential_friend_id = 0, $friend_status = false
 				);
 				break;
 
+			case 'awaiting_response' :
+				$button = array(
+					'id'                => 'awaiting_response',
+					'component'         => 'friends',
+					'must_be_logged_in' => true,
+					'block_self'        => true,
+					'wrapper_class'     => 'friendship-button awaiting_response_friend',
+					'wrapper_id'        => 'friendship-button-' . $potential_friend_id,
+					'link_href'         => bp_loggedin_user_domain() . bp_get_friends_slug() . '/requests/',
+					'link_text'         => __( 'Friendship Requested', 'buddypress' ),
+					'link_title'        => __( 'Friendship Requested', 'buddypress' ),
+					'link_id'           => 'friend-' . $potential_friend_id,
+					'link_rel'          => 'remove',
+					'link_class'        => 'friendship-button awaiting_response_friend requested'
+				);
+				break;
+
 			case 'is_friend' :
 				$button = array(
 					'id'                => 'is_friend',
@@ -329,6 +379,14 @@ function bp_add_friend_button( $potential_friend_id = 0, $friend_status = false
 		return bp_get_button( apply_filters( 'bp_get_add_friend_button', $button ) );
 	}
 
+/**
+ * Get a comma-separated list of IDs of a user's friends.
+ *
+ * @param int $user_id Optional. Default: the displayed user's ID, or the
+ *        logged-in user's ID.
+ * @return string|bool A comma-separated list of friend IDs if any are found,
+ *         otherwise false.
+ */
 function bp_get_friend_ids( $user_id = 0 ) {
 
 	if ( empty( $user_id ) )
@@ -343,13 +401,14 @@ function bp_get_friend_ids( $user_id = 0 ) {
 }
 
 /**
- * Get a user's friendship requests
+ * Get a user's friendship requests.
  *
- * Note that we return a 0 if no pending requests are found. This is necessary because of the
- * structure of the $include parameter in bp_has_members().
+ * Note that we return a 0 if no pending requests are found. This is necessary
+ * because of the structure of the $include parameter in bp_has_members().
  *
- * @param int $user_id Defaults to displayed user
- * @return mixed Returns an array of users if found, or a 0 if none are found
+ * @param int $user_id ID of the user whose requests are being retrieved.
+ *        Defaults to displayed user.
+ * @return array|int An array of user IDs if found, or a 0 if none are found.
  */
 function bp_get_friendship_requests( $user_id = 0 ) {
 	if ( !$user_id ) {
@@ -371,9 +430,17 @@ function bp_get_friendship_requests( $user_id = 0 ) {
 	return apply_filters( 'bp_get_friendship_requests', $requests );
 }
 
+/**
+ * Output the ID of the friendship between the logged-in user and the current user in the loop.
+ */
 function bp_friend_friendship_id() {
 	echo bp_get_friend_friendship_id();
 }
+	/**
+	 * Return the ID of the frinedship between the logged-in user and the current user in the loop.
+	 *
+	 * @return int ID of the friendship.
+	 */
 	function bp_get_friend_friendship_id() {
 		global $members_template;
 
@@ -385,9 +452,17 @@ function bp_friend_friendship_id() {
 		return apply_filters( 'bp_get_friend_friendship_id', $friendship_id );
 	}
 
+/**
+ * Output the URL for accepting the current friendship request in the loop.
+ */
 function bp_friend_accept_request_link() {
 	echo bp_get_friend_accept_request_link();
 }
+	/**
+	 * Return the URL for accepting the current friendship request in the loop.
+	 *
+	 * @return string accept-friendship URL.
+	 */
 	function bp_get_friend_accept_request_link() {
 		global $members_template;
 
@@ -399,9 +474,17 @@ function bp_friend_accept_request_link() {
 		return apply_filters( 'bp_get_friend_accept_request_link', wp_nonce_url( bp_loggedin_user_domain() . bp_get_friends_slug() . '/requests/accept/' . $friendship_id, 'friends_accept_friendship' ) );
 	}
 
+/**
+ * Output the URL for rejecting the current friendship request in the loop.
+ */
 function bp_friend_reject_request_link() {
 	echo bp_get_friend_reject_request_link();
 }
+	/**
+	 * Return the URL for rejecting the current friendship request in the loop.
+	 *
+	 * @return string reject-friendship URL.
+	 */
 	function bp_get_friend_reject_request_link() {
 		global $members_template;
 
@@ -413,20 +496,99 @@ function bp_friend_reject_request_link() {
 		return apply_filters( 'bp_get_friend_reject_request_link', wp_nonce_url( bp_loggedin_user_domain() . bp_get_friends_slug() . '/requests/reject/' . $friendship_id, 'friends_reject_friendship' ) );
 	}
 
+/**
+ * Output the total friend count for a given user.
+ *
+ * @param int $user_id See {@link friends_get_total_friend_count()}.
+ */
 function bp_total_friend_count( $user_id = 0 ) {
 	echo bp_get_total_friend_count( $user_id );
 }
+	/**
+	 * Return the total friend count for a given user.
+	 *
+	 * @param int $user_id See {@link friends_get_total_friend_count()}.
+	 * @return int Total friend count.
+	 */
 	function bp_get_total_friend_count( $user_id = 0 ) {
 		return apply_filters( 'bp_get_total_friend_count', friends_get_total_friend_count( $user_id ) );
 	}
 	add_filter( 'bp_get_total_friend_count', 'bp_core_number_format' );
 
+/**
+ * Output the total friendship request count for a given user.
+ *
+ * @see bp_friend_get_total_requests_count() for description of arguments.
+ *
+ * @param int $user_id See {@link bp_friend_get_total_requests_count().
+ */
 function bp_friend_total_requests_count( $user_id = 0 ) {
 	echo bp_friend_get_total_requests_count( $user_id );
 }
+	/**
+	 * Return the total friendship request count for a given user.
+	 *
+	 * @param int $user_id ID of the user whose requests are being counted.
+	 *        Default: ID of the logged-in user.
+	 * @return int Friend count.
+	 */
 	function bp_friend_get_total_requests_count( $user_id = 0 ) {
 		if ( empty( $user_id ) )
 			$user_id = bp_loggedin_user_id();
 
 		return apply_filters( 'bp_friend_get_total_requests_count', count( BP_Friends_Friendship::get_friend_user_ids( $user_id, true ) ) );
 	}
+
+/** Stats **********************************************************************/
+
+/**
+ * Display the number of friends in user's profile.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $args before|after|user_id
+ * @uses bp_friends_get_profile_stats() to get the stats
+ */
+function bp_friends_profile_stats( $args = '' ) {
+	echo bp_friends_get_profile_stats( $args );
+}
+add_action( 'bp_members_admin_user_stats', 'bp_friends_profile_stats', 7, 1 );
+
+/**
+ * Return the number of friends in user's profile.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $args before|after|user_id
+ * @return string HTML for stats output.
+ */
+function bp_friends_get_profile_stats( $args = '' ) {
+
+	// Parse the args
+	$r = bp_parse_args( $args, array(
+		'before'  => '<li class="bp-friends-profile-stats">',
+		'after'   => '</li>',
+		'user_id' => bp_displayed_user_id(),
+		'friends' => 0,
+		'output'  => ''
+	), 'friends_get_profile_stats' );
+
+	// Allow completely overloaded output
+	if ( empty( $r['output'] ) ) {
+
+		// Only proceed if a user ID was passed
+		if ( ! empty( $r['user_id'] ) ) {
+
+			// Get the user's friends
+			if ( empty( $r['friends'] ) ) {
+				$r['friends'] = absint( friends_get_total_friend_count( $r['user_id'] ) );
+			}
+
+			// If friends exist, show some formatted output
+			$r['output'] = $r['before'] . sprintf( _n( '%s friend', '%s friends', $r['friends'], 'buddypress' ), '<strong>' . $r['friends'] . '</strong>' ) . $r['after'];
+		}
+	}
+
+	// Filter and return
+	return apply_filters( 'bp_friends_get_profile_stats', $r['output'], $r );
+}
diff --git a/wp-content/plugins/buddypress/bp-friends/bp-friends-widgets.php b/wp-content/plugins/buddypress/bp-friends/bp-friends-widgets.php
new file mode 100644
index 0000000000000000000000000000000000000000..bfbdd3a7636884afd8b2674ca526cccc6294b005
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-friends/bp-friends-widgets.php
@@ -0,0 +1,250 @@
+<?php
+/**
+ * BuddyPress Widgets
+ *
+ * @package BuddyPress
+ * @subpackage Friends
+ * @since BuddyPress (1.9.0)
+ */
+
+// Exit if accessed directly
+if ( ! defined( 'ABSPATH' ) ) exit;
+
+/**
+ * Register the friends widget.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_friends_register_widgets() {
+	if ( ! bp_is_active( 'friends' ) ) {
+		return;
+	}
+
+	add_action( 'widgets_init', create_function( '', 'return register_widget("BP_Core_Friends_Widget");' ) );
+}
+add_action( 'bp_register_widgets', 'bp_friends_register_widgets' );
+
+/*** MEMBER FRIENDS WIDGET *****************/
+
+/**
+ * The User Friends widget class.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+class BP_Core_Friends_Widget extends WP_Widget {
+
+	/**
+	 * Class constructor.
+	 */
+	function __construct() {
+		$widget_ops = array(
+			'description' => __( 'A dynamic list of recently active, popular, and newest Friends of the displayed member.  Widget is only shown when viewing a member profile.', 'buddypress' ),
+			'classname' => 'widget_bp_core_friends_widget buddypress widget',
+		);
+		parent::__construct( false, $name = _x( '(BuddyPress) Friends', 'widget name', 'buddypress' ), $widget_ops );
+
+	}
+
+	/**
+	 * Display the widget.
+	 *
+	 * @param array $args Widget arguments.
+	 * @param array $instance The widget settings, as saved by the user.
+	 */
+	function widget( $args, $instance ) {
+		extract( $args );
+
+		if ( ! bp_displayed_user_id() ) {
+			return;
+		}
+
+		$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
+		wp_enqueue_script( 'bp_core_widget_friends-js', buddypress()->plugin_url . "bp-friends/js/widget-friends{$min}.js", array( 'jquery' ), bp_get_version() );
+
+		$user_id = bp_displayed_user_id();
+		$link = trailingslashit( bp_displayed_user_domain() . bp_get_friends_slug() );
+		$instance['title'] = sprintf( __( '%s&#8217;s Friends', 'buddypress' ), bp_get_displayed_user_fullname() );
+
+		if ( empty( $instance['friend_default'] ) ) {
+			$instance['friend_default'] = 'active';
+		}
+
+		$title = apply_filters( 'widget_title', $instance['title'] );
+
+		echo $before_widget;
+
+		$title = $instance['link_title'] ? '<a href="' . esc_url( $link ) . '">' . esc_html( $title ) . '</a>' : esc_html( $title );
+
+		echo $before_title . $title . $after_title;
+
+		$members_args = array(
+			'user_id'         => absint( $user_id ),
+			'type'            => sanitize_text_field( $instance['friend_default'] ),
+			'max'             => absint( $instance['max_friends'] ),
+			'populate_extras' => 1,
+		);
+
+		?>
+
+		<?php if ( bp_has_members( $members_args ) ) : ?>
+			<div class="item-options" id="friends-list-options">
+				<a href="<?php bp_members_directory_permalink(); ?>" id="newest-friends" <?php if ( $instance['friend_default'] == 'newest' ) : ?>class="selected"<?php endif; ?>><?php _e( 'Newest', 'buddypress' ) ?></a>
+				| <a href="<?php bp_members_directory_permalink(); ?>" id="recently-active-friends" <?php if ( $instance['friend_default'] == 'active' ) : ?>class="selected"<?php endif; ?>><?php _e( 'Active', 'buddypress' ) ?></a>
+				| <a href="<?php bp_members_directory_permalink(); ?>" id="popular-friends" <?php if ( $instance['friend_default'] == 'popular' ) : ?>class="selected"<?php endif; ?>><?php _e( 'Popular', 'buddypress' ) ?></a>
+			</div>
+
+			<ul id="friends-list" class="item-list">
+				<?php while ( bp_members() ) : bp_the_member(); ?>
+					<li class="vcard">
+						<div class="item-avatar">
+							<a href="<?php bp_member_permalink() ?>" title="<?php bp_member_name() ?>"><?php bp_member_avatar() ?></a>
+						</div>
+
+						<div class="item">
+							<div class="item-title fn"><a href="<?php bp_member_permalink() ?>" title="<?php bp_member_name() ?>"><?php bp_member_name() ?></a></div>
+							<div class="item-meta">
+								<span class="activity">
+								<?php
+									if ( 'newest' == $instance['friend_default'] )
+										bp_member_registered();
+									if ( 'active' == $instance['friend_default'] )
+										bp_member_last_active();
+									if ( 'popular' == $instance['friend_default'] )
+										bp_member_total_friend_count();
+								?>
+								</span>
+							</div>
+						</div>
+					</li>
+
+				<?php endwhile; ?>
+			</ul>
+			<?php wp_nonce_field( 'bp_core_widget_friends', '_wpnonce-friends' ); ?>
+			<input type="hidden" name="friends_widget_max" id="friends_widget_max" value="<?php echo absint( $instance['max_friends'] ); ?>" />
+
+		<?php else: ?>
+
+			<div class="widget-error">
+				<?php _e( 'Sorry, no members were found.', 'buddypress' ); ?>
+			</div>
+
+		<?php endif; ?>
+
+		<?php echo $after_widget; ?>
+	<?php
+	}
+
+	/**
+	 * Process a widget save.
+	 *
+	 * @param array $new_instance The parameters saved by the user.
+	 * @param array $old_instance The paramaters as previously saved to the database.
+	 * @return array $instance The processed settings to save.
+	 */
+	function update( $new_instance, $old_instance ) {
+		$instance = $old_instance;
+
+		$instance['max_friends']    = absint( $new_instance['max_friends'] );
+		$instance['friend_default'] = sanitize_text_field( $new_instance['friend_default'] );
+		$instance['link_title']	    = (bool) $new_instance['link_title'];
+
+		return $instance;
+	}
+
+	/**
+	 * Render the widget edit form.
+	 *
+	 * @param array $instance The saved widget settings.
+	 */
+	function form( $instance ) {
+		$defaults = array(
+			'max_friends' 	 => 5,
+			'friend_default' => 'active',
+			'link_title' 	 => false
+		);
+		$instance = wp_parse_args( (array) $instance, $defaults );
+
+		$max_friends 	= $instance['max_friends'];
+		$friend_default = $instance['friend_default'];
+		$link_title	= (bool) $instance['link_title'];
+		?>
+
+		<p><label for="<?php echo $this->get_field_name( 'link_title' ) ?>"><input type="checkbox" name="<?php echo $this->get_field_name('link_title') ?>" value="1" <?php checked( $link_title ) ?> /> <?php _e( 'Link widget title to Members directory', 'buddypress' ) ?></label></p>
+
+		<p><label for="bp-core-widget-friends-max"><?php _e( 'Max friends to show:', 'buddypress' ); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'max_friends' ); ?>" name="<?php echo $this->get_field_name( 'max_friends' ); ?>" type="text" value="<?php echo absint( $max_friends ); ?>" style="width: 30%" /></label></p>
+
+		<p>
+			<label for="bp-core-widget-friends-default"><?php _e( 'Default friends to show:', 'buddypress' ); ?>
+			<select name="<?php echo $this->get_field_name( 'friend_default' ) ?>">
+				<option value="newest" <?php selected( $friend_default, 'newest' ); ?>><?php _e( 'Newest', 'buddypress' ) ?></option>
+				<option value="active" <?php selected( $friend_default, 'active' );?>><?php _e( 'Active', 'buddypress' ) ?></option>
+				<option value="popular"  <?php selected( $friend_default, 'popular' ); ?>><?php _e( 'Popular', 'buddypress' ) ?></option>
+			</select>
+			</label>
+		</p>
+
+	<?php
+	}
+}
+
+/** Widget AJAX ***************************************************************/
+
+/**
+ * Process AJAX pagination or filtering for the Friends widget.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_core_ajax_widget_friends() {
+
+	check_ajax_referer( 'bp_core_widget_friends' );
+
+	switch ( $_POST['filter'] ) {
+		case 'newest-friends':
+			$type = 'newest';
+			break;
+
+		case 'recently-active-friends':
+			$type = 'active';
+			break;
+
+		case 'popular-friends':
+			$type = 'popular';
+			break;
+	}
+
+	$members_args = array(
+		'user_id'         => bp_displayed_user_id(),
+		'type'            => $type,
+		'max'             => absint( $_POST['max-friends'] ),
+		'populate_extras' => 1,
+	);
+
+	if ( bp_has_members( $members_args ) ) : ?>
+		<?php echo '0[[SPLIT]]'; // return valid result. TODO: remove this. ?>
+		<?php while ( bp_members() ) : bp_the_member(); ?>
+			<li class="vcard">
+				<div class="item-avatar">
+					<a href="<?php bp_member_permalink() ?>"><?php bp_member_avatar() ?></a>
+				</div>
+
+				<div class="item">
+					<div class="item-title fn"><a href="<?php bp_member_permalink() ?>" title="<?php bp_member_name() ?>"><?php bp_member_name() ?></a></div>
+					<?php if ( 'active' == $type ) : ?>
+						<div class="item-meta"><span class="activity"><?php bp_member_last_active() ?></span></div>
+					<?php elseif ( 'newest' == $type ) : ?>
+						<div class="item-meta"><span class="activity"><?php bp_member_registered() ?></span></div>
+					<?php elseif ( bp_is_active( 'friends' ) ) : ?>
+						<div class="item-meta"><span class="activity"><?php bp_member_total_friend_count() ?></span></div>
+					<?php endif; ?>
+				</div>
+			</li>
+		<?php endwhile; ?>
+
+	<?php else: ?>
+		<?php echo "-1[[SPLIT]]<li>"; ?>
+		<?php _e( 'There were no members found, please try another filter.', 'buddypress' ) ?>
+		<?php echo "</li>"; ?>
+	<?php endif;
+}
+add_action( 'wp_ajax_widget_friends', 'bp_core_ajax_widget_friends' );
+add_action( 'wp_ajax_nopriv_widget_friends', 'bp_core_ajax_widget_friends' );
diff --git a/wp-content/plugins/buddypress/bp-friends/js/widget-friends.js b/wp-content/plugins/buddypress/bp-friends/js/widget-friends.js
new file mode 100644
index 0000000000000000000000000000000000000000..9a1367de840133ec5d9035d5aa030c30dc3d49f2
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-friends/js/widget-friends.js
@@ -0,0 +1,49 @@
+jQuery(document).ready( function() {
+	jQuery(".widget div#friends-list-options a").on('click',
+		function() {
+			var link = this;
+			jQuery(link).addClass('loading');
+
+			jQuery(".widget div#friends-list-options a").removeClass("selected");
+			jQuery(this).addClass('selected');
+
+			jQuery.post( ajaxurl, {
+				action: 'widget_friends',
+				'cookie': encodeURIComponent(document.cookie),
+				'_wpnonce': jQuery("input#_wpnonce-friends").val(),
+				'max-friends': jQuery("input#friends_widget_max").val(),
+				'filter': jQuery(this).attr('id')
+			},
+			function(response)
+			{
+				jQuery(link).removeClass('loading');
+				friend_wiget_response(response);
+			});
+
+			return false;
+		}
+	);
+});
+
+function friend_wiget_response(response) {
+	response = response.substr(0, response.length-1);
+	response = response.split('[[SPLIT]]');
+
+	if ( response[0] != "-1" ) {
+		jQuery(".widget ul#friends-list").fadeOut(200,
+			function() {
+				jQuery(".widget ul#friends-list").html(response[1]);
+				jQuery(".widget ul#friends-list").fadeIn(200);
+			}
+		);
+
+	} else {
+		jQuery(".widget ul#friends-list").fadeOut(200,
+			function() {
+				var message = '<p>' + response[1] + '</p>';
+				jQuery(".widget ul#friends-list").html(message);
+				jQuery(".widget ul#friends-list").fadeIn(200);
+			}
+		);
+	}
+}
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-friends/js/widget-friends.min.js b/wp-content/plugins/buddypress/bp-friends/js/widget-friends.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..d26bc88d96ca7df190e63502b9b8c1dbf650de95
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-friends/js/widget-friends.min.js
@@ -0,0 +1 @@
+jQuery(document).ready(function(){jQuery(".widget div#friends-list-options a").on("click",function(){var a=this;jQuery(a).addClass("loading");jQuery(".widget div#friends-list-options a").removeClass("selected");jQuery(this).addClass("selected");jQuery.post(ajaxurl,{action:"widget_friends",cookie:encodeURIComponent(document.cookie),_wpnonce:jQuery("input#_wpnonce-friends").val(),"max-friends":jQuery("input#friends_widget_max").val(),filter:jQuery(this).attr("id")},function(b){jQuery(a).removeClass("loading");friend_wiget_response(b)});return false})});function friend_wiget_response(a){a=a.substr(0,a.length-1);a=a.split("[[SPLIT]]");if(a[0]!="-1"){jQuery(".widget ul#friends-list").fadeOut(200,function(){jQuery(".widget ul#friends-list").html(a[1]);jQuery(".widget ul#friends-list").fadeIn(200)})}else{jQuery(".widget ul#friends-list").fadeOut(200,function(){var b="<p>"+a[1]+"</p>";jQuery(".widget ul#friends-list").html(b);jQuery(".widget ul#friends-list").fadeIn(200)})}};
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-groups/admin/css/admin.css b/wp-content/plugins/buddypress/bp-groups/admin/css/admin.css
index 5a122ccd346acaefff6f2a273b9c75c02c5d3fa2..7c6d451de985f8e6b13ef1775aa76a51cd532346 100644
--- a/wp-content/plugins/buddypress/bp-groups/admin/css/admin.css
+++ b/wp-content/plugins/buddypress/bp-groups/admin/css/admin.css
@@ -46,7 +46,6 @@ ul.bp-group-delete-list {
 	bottom: 0;
 }
 .bp-group-admin-pagination-viewing {
-	font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif;
 	color: #777;
 	font-size: 12px;
 	font-style: italic;
diff --git a/wp-content/plugins/buddypress/bp-groups/admin/css/admin.min.css b/wp-content/plugins/buddypress/bp-groups/admin/css/admin.min.css
index 7983663f392124e63864add65ce35b93ddb14a58..f5841b4c2d89912cdc1e0d261facfac152842412 100644
--- a/wp-content/plugins/buddypress/bp-groups/admin/css/admin.min.css
+++ b/wp-content/plugins/buddypress/bp-groups/admin/css/admin.min.css
@@ -1 +1 @@
-body.toplevel_page_bp-groups table.groups th#status,body.toplevel_page_bp-groups table.groups th#members{width:10%}body.toplevel_page_bp-groups table.groups th#last_active{width:15%}#bp-groups-edit-form input{outline:medium none;padding:3px 8px}#bp-groups-edit-form input#bp-groups-name{font-size:1.7em;width:100%}#bp-groups-edit-form input#bp-groups-new-members{width:100%;max-width:90%;border:0}.bp-groups-settings-section{margin-bottom:15px}.bp-groups-member-type{position:relative;padding-bottom:1.7em}.bp-groups-member-type>h4{margin-bottom:.5em}ul.bp-group-delete-list{list-style-type:disc;margin:4px 26px}.bp-group-admin-pagination{position:absolute;text-align:right;width:100%}.bp-group-admin-pagination.table-top{top:0}.bp-group-admin-pagination.table-bottom{bottom:0}.bp-group-admin-pagination-viewing{font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;color:#777;font-size:12px;font-style:italic}.bp-group-admin-pagination-links{white-space:nowrap;padding-left:15px}
\ No newline at end of file
+body.toplevel_page_bp-groups table.groups th#status,body.toplevel_page_bp-groups table.groups th#members{width:10%}body.toplevel_page_bp-groups table.groups th#last_active{width:15%}#bp-groups-edit-form input{outline:medium none;padding:3px 8px}#bp-groups-edit-form input#bp-groups-name{font-size:1.7em;width:100%}#bp-groups-edit-form input#bp-groups-new-members{width:100%;max-width:90%;border:0}.bp-groups-settings-section{margin-bottom:15px}.bp-groups-member-type{position:relative;padding-bottom:1.7em}.bp-groups-member-type>h4{margin-bottom:.5em}ul.bp-group-delete-list{list-style-type:disc;margin:4px 26px}.bp-group-admin-pagination{position:absolute;text-align:right;width:100%}.bp-group-admin-pagination.table-top{top:0}.bp-group-admin-pagination.table-bottom{bottom:0}.bp-group-admin-pagination-viewing{color:#777;font-size:12px;font-style:italic}.bp-group-admin-pagination-links{white-space:nowrap;padding-left:15px}
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-actions.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-actions.php
index ed4d3add6ad8fc4b73eab49ee5f8681251571627..2a0ea8badcffb7845511d44e17e540ddee9fd329 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-actions.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-actions.php
@@ -3,9 +3,9 @@
 /**
  * BuddyPress Groups Actions
  *
- * Action functions are exactly the same as screen functions, however they do not
- * have a template screen associated with them. Usually they will send the user
- * back to the default screen after execution.
+ * Action functions are exactly the same as screen functions, however they do
+ * not have a template screen associated with them. Usually they will send the
+ * user back to the default screen after execution.
  *
  * @package BuddyPress
  * @subpackage GroupsActions
@@ -14,6 +14,9 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Catch and process group creation form submissions.
+ */
 function groups_action_create_group() {
 	global $bp;
 
@@ -42,7 +45,8 @@ function groups_action_create_group() {
 		setcookie( 'bp_completed_create_steps', false, time() - 1000, COOKIEPATH );
 
 		$reset_steps = true;
-		bp_core_redirect( bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create/step/' . array_shift( array_keys( $bp->groups->group_creation_steps ) ) . '/' );
+		$keys        = array_keys( $bp->groups->group_creation_steps );
+		bp_core_redirect( bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create/step/' . array_shift( $keys ) . '/' );
 	}
 
 	// If this is a creation step that is not recognized, just redirect them back to the first screen
@@ -59,6 +63,12 @@ function groups_action_create_group() {
 	if ( isset( $_COOKIE['bp_new_group_id'] ) ) {
 		$bp->groups->new_group_id = $_COOKIE['bp_new_group_id'];
 		$bp->groups->current_group = groups_get_group( array( 'group_id' => $bp->groups->new_group_id ) );
+
+		// Only allow the group creator to continue to edit the new group
+		if ( ! bp_is_group_creator( $bp->groups->current_group, bp_loggedin_user_id() ) ) {
+			bp_core_add_message( __( 'Only the group creator may continue editing this group.', 'buddypress' ), 'error' );
+			bp_core_redirect( bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create/' );
+		}
 	}
 
 	// If the save, upload or skip button is hit, lets calculate what we need to save
@@ -112,8 +122,18 @@ function groups_action_create_group() {
 			groups_update_groupmeta( $bp->groups->new_group_id, 'invite_status', $invite_status );
 		}
 
-		if ( 'group-invites' == bp_get_groups_current_create_step() )
+		if ( 'group-invites' === bp_get_groups_current_create_step() ) {
+			if ( ! empty( $_POST['friends'] ) ) {
+				foreach ( (array) $_POST['friends'] as $friend ) {
+					groups_invite_user( array(
+						'user_id'  => $friend,
+						'group_id' => $bp->groups->new_group_id,
+					) );
+				}
+			}
+
 			groups_send_invites( bp_loggedin_user_id(), $bp->groups->new_group_id );
+		}
 
 		do_action( 'groups_create_group_step_save_' . bp_get_groups_current_create_step() );
 		do_action( 'groups_create_group_step_complete' ); // Mostly for clearing cache on a generic action name
@@ -133,13 +153,13 @@ function groups_action_create_group() {
 
 		// If we have completed all steps and hit done on the final step we
 		// can redirect to the completed group
-		if ( count( $bp->groups->completed_create_steps ) == count( $bp->groups->group_creation_steps ) && bp_get_groups_current_create_step() == array_pop( array_keys( $bp->groups->group_creation_steps ) ) ) {
+		$keys = array_keys( $bp->groups->group_creation_steps );
+		if ( count( $bp->groups->completed_create_steps ) == count( $keys ) && bp_get_groups_current_create_step() == array_pop( $keys ) ) {
 			unset( $bp->groups->current_create_step );
 			unset( $bp->groups->completed_create_steps );
 
 			// Once we compelete all steps, record the group creation in the activity stream.
 			groups_record_activity( array(
-				'action' => apply_filters( 'groups_activity_created_group_action', sprintf( __( '%1$s created the group %2$s', 'buddypress'), bp_core_get_userlink( bp_loggedin_user_id() ), '<a href="' . bp_get_group_permalink( $bp->groups->current_group ) . '">' . esc_attr( $bp->groups->current_group->name ) . '</a>' ) ),
 				'type' => 'created_group',
 				'item_id' => $bp->groups->new_group_id
 			) );
@@ -152,7 +172,7 @@ function groups_action_create_group() {
 			 * Since we don't know what the next step is going to be (any plugin can insert steps)
 			 * we need to loop the step array and fetch the next step that way.
 			 */
-			foreach ( (array) $bp->groups->group_creation_steps as $key => $value ) {
+			foreach ( $keys as $key ) {
 				if ( $key == bp_get_groups_current_create_step() ) {
 					$next = 1;
 					continue;
@@ -168,6 +188,24 @@ function groups_action_create_group() {
 		}
 	}
 
+	// Remove invitations
+	if ( 'group-invites' === bp_get_groups_current_create_step() && ! empty( $_REQUEST['user_id'] ) && is_numeric( $_REQUEST['user_id'] ) ) {
+		if ( ! check_admin_referer( 'groups_invite_uninvite_user' ) ) {
+			return false;
+		}
+
+		$message = __( 'Invite successfully removed', 'buddypress' );
+		$error   = false;
+
+		if( ! groups_uninvite_user( (int) $_REQUEST['user_id'], $bp->groups->new_group_id ) ) {
+			$message = __( 'There was an error removing the invite', 'buddypress' );
+			$error   = 'error';
+		}
+
+		bp_core_add_message( $message, $error );
+		bp_core_redirect( bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create/step/group-invites/' );
+	}
+
 	// Group avatar is handled separately
 	if ( 'group-avatar' == bp_get_groups_current_create_step() && isset( $_POST['upload'] ) ) {
 		if ( ! isset( $bp->avatar_admin ) ) {
@@ -235,38 +273,58 @@ function groups_action_join_group() {
 }
 add_action( 'bp_actions', 'groups_action_join_group' );
 
-
+/**
+ * Catch and process "Leave Group" button clicks.
+ *
+ * When a group member clicks on the "Leave Group" button from a group's page,
+ * this function is run.
+ *
+ * Note: When leaving a group from the group directory, AJAX is used and
+ * another function handles this. See {@link bp_legacy_theme_ajax_joinleave_group()}.
+ *
+ * @since BuddyPress (1.2.4)
+ */
 function groups_action_leave_group() {
-	global $bp;
-
-	if ( !bp_is_single_item() || !bp_is_groups_component() || !bp_is_current_action( 'leave-group' ) )
+	if ( ! bp_is_single_item() || ! bp_is_groups_component() || ! bp_is_current_action( 'leave-group' ) ) {
 		return false;
+	}
 
 	// Nonce check
-	if ( !check_admin_referer( 'groups_leave_group' ) )
+	if ( ! check_admin_referer( 'groups_leave_group' ) ) {
 		return false;
+	}
 
 	// User wants to leave any group
-	if ( groups_is_user_member( bp_loggedin_user_id(), $bp->groups->current_group->id ) ) {
+	if ( groups_is_user_member( bp_loggedin_user_id(), bp_get_current_group_id() ) ) {
+		$bp = buddypress();
 
 		// Stop sole admins from abandoning their group
-		$group_admins = groups_get_group_admins( $bp->groups->current_group->id );
-	 	if ( 1 == count( $group_admins ) && $group_admins[0]->user_id == bp_loggedin_user_id() )
-			bp_core_add_message( __( 'This group must have at least one admin', 'buddypress' ), 'error' );
+		$group_admins = groups_get_group_admins( bp_get_current_group_id() );
 
-		elseif ( !groups_leave_group( $bp->groups->current_group->id ) )
+	 	if ( 1 == count( $group_admins ) && $group_admins[0]->user_id == bp_loggedin_user_id() ) {
+			bp_core_add_message( __( 'This group must have at least one admin', 'buddypress' ), 'error' );
+		} elseif ( ! groups_leave_group( $bp->groups->current_group->id ) ) {
 			bp_core_add_message( __( 'There was an error leaving the group.', 'buddypress' ), 'error' );
-		else
+		} else {
 			bp_core_add_message( __( 'You successfully left the group.', 'buddypress' ) );
+		}
 
-		bp_core_redirect( bp_get_group_permalink( $bp->groups->current_group ) );
+		$redirect = bp_get_group_permalink( groups_get_current_group() );
+
+		if( 'hidden' == $bp->groups->current_group->status ) {
+			$redirect = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() );
+		}
+
+		bp_core_redirect( $redirect );
 	}
 
 	bp_core_load_template( apply_filters( 'groups_template_group_home', 'groups/single/home' ) );
 }
 add_action( 'bp_actions', 'groups_action_leave_group' );
 
-
+/**
+ * Sort the group creation steps.
+ */
 function groups_action_sort_creation_steps() {
 	global $bp;
 
@@ -292,7 +350,7 @@ function groups_action_sort_creation_steps() {
 }
 
 /**
- * Catches requests for a random group page (example.com/groups/?random-group) and redirects
+ * Catch requests for a random group page (example.com/groups/?random-group) and redirect.
  */
 function groups_action_redirect_to_random_group() {
 
@@ -305,9 +363,9 @@ function groups_action_redirect_to_random_group() {
 add_action( 'bp_actions', 'groups_action_redirect_to_random_group' );
 
 /**
- * Load the activity feed for the specific group.
+ * Load the activity feed for the current group.
  *
- * @since BuddyPress (v1.2)
+ * @since BuddyPress (1.2.0)
  */
 function groups_action_group_feed() {
 
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-activity.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-activity.php
index e32f936b32a38418f99f1c919855f9eb4ec822e8..b7f1b1b5bb411ca2fbfe01fb1a4490c8a2965159 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-activity.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-activity.php
@@ -13,6 +13,9 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Register activity actions for the Groups component.
+ */
 function groups_register_activity_actions() {
 	global $bp;
 
@@ -20,8 +23,19 @@ function groups_register_activity_actions() {
 		return false;
 	}
 
-	bp_activity_set_action( $bp->groups->id, 'created_group',   __( 'Created a group',       'buddypress' ) );
-	bp_activity_set_action( $bp->groups->id, 'joined_group',    __( 'Joined a group',        'buddypress' ) );
+	bp_activity_set_action(
+		$bp->groups->id,
+		'created_group',
+		__( 'Created a group', 'buddypress' ),
+		'bp_groups_format_activity_action_created_group'
+	);
+
+	bp_activity_set_action(
+		$bp->groups->id,
+		'joined_group',
+		__( 'Joined a group', 'buddypress' ),
+		'bp_groups_format_activity_action_joined_group'
+	);
 
 	// These actions are for the legacy forums
 	// Since the bbPress plugin also shares the same 'forums' identifier, we also
@@ -35,11 +49,139 @@ function groups_register_activity_actions() {
 }
 add_action( 'bp_register_activity_actions', 'groups_register_activity_actions' );
 
+/**
+ * Format 'created_group' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param object $activity Activity data object.
+ * @return string
+ */
+function bp_groups_format_activity_action_created_group( $action, $activity ) {
+	$user_link = bp_core_get_userlink( $activity->user_id );
+
+	$group = groups_get_group( array(
+		'group_id'        => $activity->item_id,
+		'populate_extras' => false,
+	) );
+	$group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
+
+	$action = sprintf( __( '%1$s created the group %2$s', 'buddypress'), $user_link, $group_link );
+
+	return apply_filters( 'groups_activity_created_group_action', $action, $activity );
+}
+
+/**
+ * Format 'joined_group' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param object $activity Activity data object.
+ * @return string
+ */
+function bp_groups_format_activity_action_joined_group( $action, $activity ) {
+	$user_link = bp_core_get_userlink( $activity->user_id );
+
+	$group = groups_get_group( array(
+		'group_id'        => $activity->item_id,
+		'populate_extras' => false,
+	) );
+	$group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
+
+	$action = sprintf( __( '%1$s joined the group %2$s', 'buddypress' ), $user_link, $group_link );
+
+	// Legacy filters (do not follow parameter patterns of other activity
+	// action filters, and requires apply_filters_ref_array())
+	if ( has_filter( 'groups_activity_membership_accepted_action' ) ) {
+		$action = apply_filters_ref_array( 'groups_activity_membership_accepted_action', array( $action, $user_link, &$group ) );
+	}
+
+	// Another legacy filter
+	if ( has_filter( 'groups_activity_accepted_invite_action' ) ) {
+		$action = apply_filters_ref_array( 'groups_activity_accepted_invite_action', array( $action, $activity->user_id, &$group ) );
+	}
+
+	return apply_filters( 'bp_groups_format_activity_action_joined_group', $action, $activity );
+}
+
+/**
+ * Fetch data related to groups at the beginning of an activity loop.
+ *
+ * This reduces database overhead during the activity loop.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $activities Array of activity items.
+ * @return array
+ */
+function bp_groups_prefetch_activity_object_data( $activities ) {
+	$group_ids = array();
+
+	if ( empty( $activities ) ) {
+		return $activities;
+	}
+
+	foreach ( $activities as $activity ) {
+		if ( buddypress()->groups->id !== $activity->component ) {
+			continue;
+		}
+
+		$group_ids[] = $activity->item_id;
+	}
+
+	if ( ! empty( $group_ids ) ) {
+
+		// TEMPORARY - Once the 'populate_extras' issue is solved
+		// in the groups component, we can do this with groups_get_groups()
+		// rather than manually
+		$uncached_ids = array();
+		foreach ( $group_ids as $group_id ) {
+			if ( false === wp_cache_get( $group_id, 'bp_groups' ) ) {
+				$uncached_ids[] = $group_id;
+			}
+		}
+
+		if ( ! empty( $uncached_ids ) ) {
+			global $wpdb, $bp;
+			$uncached_ids_sql = implode( ',', wp_parse_id_list( $uncached_ids ) );
+			$groups = $wpdb->get_results( "SELECT * FROM {$bp->groups->table_name} WHERE id IN ({$uncached_ids_sql})" );
+			foreach ( $groups as $group ) {
+				wp_cache_set( $group->id, $group, 'bp_groups' );
+			}
+		}
+	}
+
+	return $activities;
+}
+add_filter( 'bp_activity_prefetch_object_data', 'bp_groups_prefetch_activity_object_data' );
+
+/**
+ * Record an activity item related to the Groups component.
+ *
+ * A wrapper for {@link bp_activity_add()} that provides some Groups-specific
+ * defaults.
+ *
+ * @see bp_activity_add() for more detailed description of parameters and
+ *      return values.
+ *
+ * @param array $args {
+ *     An array of arguments for the new activity item. Accepts all parameters
+ *     of {@link bp_activity_add()}. However, this wrapper provides some
+ *     additional defaults, as described below:
+ *     @type string $component Default: the id of your Groups component
+ *           (usually 'groups').
+ *     @type bool $hide_sitewide Default: True if the current group is not
+ *           public, otherwise false.
+ * }
+ * @return bool See {@link bp_activity_add()}.
+ */
 function groups_record_activity( $args = '' ) {
-	global $bp;
 
-	if ( !bp_is_active( 'activity' ) )
+	if ( ! bp_is_active( 'activity' ) ) {
 		return false;
+	}
 
 	// Set the default for hide_sitewide by checking the status of the group
 	$hide_sitewide = false;
@@ -55,34 +197,38 @@ function groups_record_activity( $args = '' ) {
 		}
 	}
 
-	$defaults = array (
+	$r = wp_parse_args( $args, array(
 		'id'                => false,
 		'user_id'           => bp_loggedin_user_id(),
 		'action'            => '',
 		'content'           => '',
 		'primary_link'      => '',
-		'component'         => $bp->groups->id,
+		'component'         => buddypress()->groups->id,
 		'type'              => false,
 		'item_id'           => false,
 		'secondary_item_id' => false,
 		'recorded_time'     => bp_core_current_time(),
 		'hide_sitewide'     => $hide_sitewide
-	);
-
-	$r = wp_parse_args( $args, $defaults );
-	extract( $r );
+	) );
 
-	return bp_activity_add( array( 'id' => $id, 'user_id' => $user_id, 'action' => $action, 'content' => $content, 'primary_link' => $primary_link, 'component' => $component, 'type' => $type, 'item_id' => $item_id, 'secondary_item_id' => $secondary_item_id, 'recorded_time' => $recorded_time, 'hide_sitewide' => $hide_sitewide ) );
+	return bp_activity_add( $r );
 }
 
+/**
+ * Update the last_activity meta value for a given group.
+ *
+ * @param int $group_id Optional. The ID of the group whose last_activity is
+ *        being updated. Default: the current group's ID.
+ */
 function groups_update_last_activity( $group_id = 0 ) {
-	global $bp;
 
-	if ( empty( $group_id ) )
-		$group_id = $bp->groups->current_group->id;
+	if ( empty( $group_id ) ) {
+		$group_id = buddypress()->groups->current_group->id;
+	}
 
-	if ( empty( $group_id ) )
+	if ( empty( $group_id ) ) {
 		return false;
+	}
 
 	groups_update_groupmeta( $group_id, 'last_activity', bp_core_current_time() );
 }
@@ -91,231 +237,78 @@ add_action( 'groups_created_group',        'groups_update_last_activity' );
 add_action( 'groups_new_forum_topic',      'groups_update_last_activity' );
 add_action( 'groups_new_forum_topic_post', 'groups_update_last_activity' );
 
-function groups_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
-
-	switch ( $action ) {
-		case 'new_membership_request':
-			$group_id = $secondary_item_id;
-			$requesting_user_id = $item_id;
-
-			$group = groups_get_group( array( 'group_id' => $group_id ) );
-			$group_link = bp_get_group_permalink( $group );
-
-			// Set up the string and the filter
-			// Because different values are passed to the filters, we'll return the
-			// values inline
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( '%1$d new membership requests for the group "%2$s"', 'buddypress' ), (int) $total_items, $group->name );
-				$filter = 'bp_groups_multiple_new_membership_requests_notification';
-				$notification_link = $group_link . 'admin/membership-requests/?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Group Membership Requests', 'buddypress' ) . '">' . $text . '</a>', $group_link, $total_items, $group->name, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $group_link, $total_items, $group->name, $text, $notification_link );
-				}
-			} else {
-				$user_fullname = bp_core_get_user_displayname( $requesting_user_id );
-				$text = sprintf( __( '%s requests group membership', 'buddypress' ), $user_fullname );
-				$filter = 'bp_groups_single_new_membership_request_notification';
-				$notification_link = $group_link . 'admin/membership-requests/?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . sprintf( __( '%s requests group membership', 'buddypress' ), $user_fullname ) . '">' . $text . '</a>', $group_link, $user_fullname, $group->name, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $group_link, $user_fullname, $group->name, $text, $notification_link );
-				}
-			}
+/**
+ * Add an activity stream item when a member joins a group
+ *
+ * @since BuddyPress (1.9.0)
+ * @param int $user_id
+ * @param int $group_id
+ */
+function bp_groups_membership_accepted_add_activity( $user_id, $group_id ) {
 
-			break;
-
-		case 'membership_request_accepted':
-			$group_id = $item_id;
-
-			$group = groups_get_group( array( 'group_id' => $group_id ) );
-			$group_link = bp_get_group_permalink( $group );
-
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( '%d accepted group membership requests', 'buddypress' ), (int) $total_items, $group->name );
-				$filter = 'bp_groups_multiple_membership_request_accepted_notification';
-				$notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Groups', 'buddypress' ) . '">' . $text . '</a>', $total_items, $group->name, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $total_items, $group->name, $text, $notification_link );
-				}
-			} else {
-				$text = sprintf( __( 'Membership for group "%s" accepted', 'buddypress' ), $group->name );
-				$filter = 'bp_groups_single_membership_request_accepted_notification';
-				$notification_link = $group_link . '?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $group_link, $group->name, $text, $notification_link );
-				}
-			}
+	// Bail if Activity is not active
+	if ( ! bp_is_active( 'activity' ) ) {
+		return false;
+	}
 
-			break;
-
-		case 'membership_request_rejected':
-			$group_id = $item_id;
-
-			$group = groups_get_group( array( 'group_id' => $group_id ) );
-			$group_link = bp_get_group_permalink( $group );
-
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( '%d rejected group membership requests', 'buddypress' ), (int) $total_items, $group->name );
-				$filter = 'bp_groups_multiple_membership_request_rejected_notification';
-				$notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Groups', 'buddypress' ) . '">' . $text . '</a>', $total_items, $group->name );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $total_items, $group->name, $text, $notification_link );
-				}
-			} else {
-				$text = sprintf( __( 'Membership for group "%s" rejected', 'buddypress' ), $group->name );
-				$filter = 'bp_groups_single_membership_request_rejected_notification';
-				$notification_link = $group_link . '?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $group_link, $group->name, $text, $notification_link );
-				}
-			}
+	// Get the group so we can get it's name
+	$group = groups_get_group( array( 'group_id' => $group_id ) );
 
-			break;
-
-		case 'member_promoted_to_admin':
-			$group_id = $item_id;
-
-			$group = groups_get_group( array( 'group_id' => $group_id ) );
-			$group_link = bp_get_group_permalink( $group );
-
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( 'You were promoted to an admin in %d groups', 'buddypress' ), (int) $total_items );
-				$filter = 'bp_groups_multiple_member_promoted_to_admin_notification';
-				$notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Groups', 'buddypress' ) . '">' . $text . '</a>', $total_items, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $total_items, $text, $notification_link );
-				}
-			} else {
-				$text = sprintf( __( 'You were promoted to an admin in the group "%s"', 'buddypress' ), $group->name );
-				$filter = 'bp_groups_single_member_promoted_to_admin_notification';
-				$notification_link = $group_link . '?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $group_link, $group->name, $text, $notification_link );
-				}
-			}
+	// Record in activity streams
+	groups_record_activity( array(
+		'action'  => apply_filters_ref_array( 'groups_activity_membership_accepted_action', array( sprintf( __( '%1$s joined the group %2$s', 'buddypress' ), bp_core_get_userlink( $user_id ), '<a href="' . bp_get_group_permalink( $group ) . '">' . esc_attr( $group->name ) . '</a>' ), $user_id, &$group ) ),
+		'type'    => 'joined_group',
+		'item_id' => $group_id,
+		'user_id' => $user_id
+	) );
+}
+add_action( 'groups_membership_accepted', 'bp_groups_membership_accepted_add_activity', 10, 2 );
 
-			break;
-
-		case 'member_promoted_to_mod':
-			$group_id = $item_id;
-
-			$group = groups_get_group( array( 'group_id' => $group_id ) );
-			$group_link = bp_get_group_permalink( $group );
-
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( 'You were promoted to a mod in %d groups', 'buddypress' ), (int) $total_items );
-				$filter = 'bp_groups_multiple_member_promoted_to_mod_notification';
-				$notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Groups', 'buddypress' ) . '">' . $text . '</a>', $total_items, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $total_items, $text, $notification_link );
-				}
-			} else {
-				$text = sprintf( __( 'You were promoted to a mod in the group "%s"', 'buddypress' ), $group->name );
-				$filter = 'bp_groups_single_member_promoted_to_mod_notification';
-				$notification_link = $group_link . '?n=1';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $group_link, $group->name, $text, $notification_link );
-				}
-			}
+/**
+ * Delete all group activity from activity streams
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_groups_delete_group_delete_all_activity( $group_id ) {
+	if ( bp_is_active( 'activity' ) ) {
+		bp_activity_delete_by_item_id( array(
+			'item_id'   => $group_id,
+			'component' => buddypress()->groups->id
+		) );
+	}
+}
+add_action( 'groups_delete_group', 'bp_groups_delete_group_delete_all_activity', 10 );
 
-			break;
-
-		case 'group_invite':
-			$group_id = $item_id;
-			$group = groups_get_group( array( 'group_id' => $group_id ) );
-			$group_link = bp_get_group_permalink( $group );
-
-			$notification_link = bp_loggedin_user_domain() . bp_get_groups_slug() . '/invites/?n=1';
-
-			if ( (int) $total_items > 1 ) {
-				$text = sprintf( __( 'You have %d new group invitations', 'buddypress' ), (int) $total_items );
-				$filter = 'bp_groups_multiple_group_invite_notification';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Group Invites', 'buddypress' ) . '">' . $text . '</a>', $total_items, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $total_items, $text, $notification_link );
-				}
-			} else {
-				$text = sprintf( __( 'You have an invitation to the group: %s', 'buddypress' ), $group->name );
-				$filter = 'bp_groups_single_group_invite_notification';
-
-				if ( 'string' == $format ) {
-					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
-				} else {
-					return apply_filters( $filter, array(
-						'link' => $notification_link,
-						'text' => $text
-					), $group_link, $group->name, $text, $notification_link );
-				}
-			}
+/**
+ * Delete group member activity if they leave or are removed within 5 minutes of
+ * membership modification.
+ *
+ * If the user joined this group less than five minutes ago, remove the
+ * joined_group activity so users cannot flood the activity stream by
+ * joining/leaving the group in quick succession.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_groups_leave_group_delete_recent_activity( $group_id, $user_id ) {
 
-			break;
+	// Bail if Activity component is not active
+	if ( ! bp_is_active( 'activity' ) ) {
+		return;
 	}
 
-	do_action( 'groups_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
-
-	return false;
+	// Get the member's group membership information
+	$membership = new BP_Groups_Member( $user_id, $group_id );
+
+	// Check the time period, and maybe delete their recent group activity
+	if ( time() <= strtotime( '+5 minutes', (int) strtotime( $membership->date_modified ) ) ) {
+		bp_activity_delete( array(
+			'component' => buddypress()->groups->id,
+			'type'      => 'joined_group',
+			'user_id'   => $user_id,
+			'item_id'   => $group_id
+		) );
+	}
 }
+add_action( 'groups_leave_group',   'bp_groups_leave_group_delete_recent_activity', 10, 2 );
+add_action( 'groups_remove_member', 'bp_groups_leave_group_delete_recent_activity', 10, 2 );
+add_action( 'groups_ban_member',    'bp_groups_leave_group_delete_recent_activity', 10, 2 );
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-admin.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-admin.php
index 294e0838f4ed4c892fe6ffa0a0ee425dfc72af5e..82d74fedc190327ecf7a522823204ade7dcd8086 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-admin.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-admin.php
@@ -2,11 +2,11 @@
 /**
  * BuddyPress Groups component admin screen
  *
- * Props to WordPress core for the Comments admin screen, and its contextual help text,
- * on which this implementation is heavily based.
+ * Props to WordPress core for the Comments admin screen, and its contextual
+ * help text, on which this implementation is heavily based.
  *
  * @package BuddyPress
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  * @subpackage Groups
  */
 
@@ -21,20 +21,17 @@ if ( is_admin() && ! empty( $_REQUEST['page'] ) && 'bp-groups' == $_REQUEST['pag
 	add_filter( 'set-screen-option', 'bp_groups_admin_screen_options', 10, 3 );
 
 /**
- * Registers the Groups component admin screen
+ * Register the Groups component admin screen.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_groups_add_admin_menu() {
 
-	if ( ! bp_current_user_can( 'bp_moderate' ) )
-		return;
-
 	// Add our screen
 	$hook = add_menu_page(
 		__( 'Groups', 'buddypress' ),
 		__( 'Groups', 'buddypress' ),
-		'manage_options',
+		'bp_moderate',
 		'bp-groups',
 		'bp_groups_admin',
 		'div'
@@ -46,12 +43,15 @@ function bp_groups_add_admin_menu() {
 add_action( bp_core_admin_hook(), 'bp_groups_add_admin_menu' );
 
 /**
- * Add groups component to custom menus array
+ * Add groups component to custom menus array.
+ *
+ * This ensures that the Groups menu item appears in the proper order on the
+ * main Dashboard menu.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
- * @param array $custom_menus
- * @return array
+ * @param array $custom_menus Array of BP top-level menu items.
+ * @return array Menu item array, with Groups added.
  */
 function bp_groups_admin_menu_order( $custom_menus = array() ) {
 	array_push( $custom_menus, 'bp-groups' );
@@ -60,11 +60,15 @@ function bp_groups_admin_menu_order( $custom_menus = array() ) {
 add_filter( 'bp_admin_menu_order', 'bp_groups_admin_menu_order' );
 
 /**
- * Set up the admin page before any output is sent. Register contextual help and screen options for this admin page.
+ * Set up the Groups admin page.
+ *
+ * Loaded before the page is rendered, this function does all initial setup,
+ * including: processing form requests, registering contextual help, and
+ * setting up screen options.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @global object $bp BuddyPress global settings
  * @global BP_Groups_List_Table $bp_groups_list_table Groups screen list table
- * @since BuddyPress (1.7)
  */
 function bp_groups_admin_load() {
 	global $bp_groups_list_table;
@@ -127,7 +131,6 @@ function bp_groups_admin_load() {
 		// Enqueue javascripts
 		wp_enqueue_script( 'postbox' );
 		wp_enqueue_script( 'dashboard' );
-		wp_enqueue_script( 'comment' );
 
 	// Index screen
 	} else {
@@ -161,9 +164,11 @@ function bp_groups_admin_load() {
 		);
 	}
 
+	$bp = buddypress();
+
 	// Enqueue CSS and JavaScript
-	wp_enqueue_script( 'bp_groups_admin_js', BP_PLUGIN_URL . "bp-groups/admin/js/admin.{$min}js", array( 'jquery', 'wp-ajax-response', 'jquery-ui-autocomplete' ), bp_get_version(), true );
-	wp_enqueue_style( 'bp_groups_admin_css', BP_PLUGIN_URL . "bp-groups/admin/css/admin.{$min}css", array(), bp_get_version() );
+	wp_enqueue_script( 'bp_groups_admin_js', $bp->plugin_url . "bp-groups/admin/js/admin.{$min}js", array( 'jquery', 'wp-ajax-response', 'jquery-ui-autocomplete' ), bp_get_version(), true );
+	wp_enqueue_style( 'bp_groups_admin_css', $bp->plugin_url . "bp-groups/admin/css/admin.{$min}css", array(), bp_get_version() );
 
 	wp_localize_script( 'bp_groups_admin_js', 'BP_Group_Admin', array(
 		'add_member_placeholder' => __( 'Start typing a username to add a new member.', 'buddypress' ),
@@ -236,12 +241,16 @@ function bp_groups_admin_load() {
 
 				// Make sure the user exists before attempting
 				// to add to the group
-				if ( ! $user_id = username_exists( $un ) ) {
-					$error_new[]   = $un;
-				} else if ( ! groups_join_group( $group_id, $user_id ) ) {
-					$error_new[]   = $un;
+				$user = get_user_by( 'slug', $un );
+
+				if ( empty( $user ) ) {
+					$error_new[] = $un;
 				} else {
-					$success_new[] = $un;
+					if ( ! groups_join_group( $group_id, $user->ID ) ) {
+						$error_new[]   = $un;
+					} else {
+						$success_new[] = $un;
+					}
 				}
 			}
 		}
@@ -374,13 +383,13 @@ function bp_groups_admin_load() {
 }
 
 /**
- * Handle save/update of screen options for the Groups component admin screen
+ * Handle save/update of screen options for the Groups component admin screen.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  *
  * @param string $value Will always be false unless another plugin filters it first.
- * @param string $option Screen option name
- * @param string $new_value Screen option form value
+ * @param string $option Screen option name.
+ * @param string $new_value Screen option form value.
  * @return string Option value. False to abandon update.
  */
 function bp_groups_admin_screen_options( $value, $option, $new_value ) {
@@ -396,13 +405,13 @@ function bp_groups_admin_screen_options( $value, $option, $new_value ) {
 }
 
 /**
- * Outputs the Groups component admin screens
+ * Select the appropirate Groups admin screen, and output it.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_groups_admin() {
 	// Decide whether to load the index or edit screen
-	$doaction = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
+	$doaction = bp_admin_list_table_current_bulk_action();
 
 	// Display the single group edit screen
 	if ( 'edit' == $doaction && ! empty( $_GET['gid'] ) ) {
@@ -419,13 +428,13 @@ function bp_groups_admin() {
 }
 
 /**
- * Display the single groups edit screen
+ * Display the single groups edit screen.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_groups_admin_edit() {
 
-	if ( ! is_super_admin() )
+	if ( ! current_user_can( 'bp_moderate' ) )
 		die( '-1' );
 
 	$messages = array();
@@ -542,12 +551,12 @@ function bp_groups_admin_edit() {
 }
 
 /**
- * Display the Group delete confirmation screen
+ * Display the Group delete confirmation screen.
  *
  * We include a separate confirmation because group deletion is truly
  * irreversible.
  *
- * @since (BuddyPress) 1.7
+ * @since BuddyPress (1.7.0)
  */
 function bp_groups_admin_delete() {
 
@@ -559,7 +568,11 @@ function bp_groups_admin_delete() {
 		$group_ids = explode( ',', $group_ids );
 	}
 	$group_ids = wp_parse_id_list( $group_ids );
-	$groups    = groups_get_groups( array( 'include' => $group_ids, 'show_hidden' => true, ) );
+	$groups    = groups_get_groups( array(
+		'include'     => $group_ids,
+		'show_hidden' => true,
+		'per_page'    => null, // Return all results
+	) );
 
 	// Create a new list of group ids, based on those that actually exist
 	$gids = array();
@@ -590,12 +603,14 @@ function bp_groups_admin_delete() {
 }
 
 /**
- * Display the Groups admin index screen, which contains a list of all your
- * BuddyPress groups.
+ * Display the Groups admin index screen.
+ *
+ * This screen contains a list of all BuddyPress groups.
  *
- * @global BP_Group_List_Table $bp_groups_list_table Group screen list table
- * @global string $plugin_page
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @global BP_Group_List_Table $bp_groups_list_table Group screen list table.
+ * @global string $plugin_page Currently viewed plugin page.
  */
 function bp_groups_admin_index() {
 	global $bp_groups_list_table, $plugin_page;
@@ -651,10 +666,11 @@ function bp_groups_admin_index() {
 }
 
 /**
- * Settings metabox
+ * Markup for the single group's Settings metabox.
+ *
+ * @since BuddyPress (1.7.0)
  *
- * @param object $item Group item
- * @since BuddyPress (1.7)
+ * @param object $item Information about the current group.
  */
 function bp_groups_admin_edit_metabox_settings( $item ) {
 
@@ -667,46 +683,52 @@ function bp_groups_admin_edit_metabox_settings( $item ) {
 	<?php endif; ?>
 
 	<div class="bp-groups-settings-section" id="bp-groups-settings-section-status">
-		<label for="group-status"><?php _e( 'Privacy', 'buddypress' ); ?></label>
-
-		<ul>
-			<li><input type="radio" name="group-status" id="bp-group-status-public" value="public" <?php checked( $item->status, 'public' ) ?> /> <?php _e( 'Public', 'buddypress' ) ?></li>
-			<li><input type="radio" name="group-status" id="bp-group-status-private" value="private" <?php checked( $item->status, 'private' ) ?> /> <?php _e( 'Private', 'buddypress' ) ?></li>
-			<li><input type="radio" name="group-status" id="bp-group-status-hidden" value="hidden" <?php checked( $item->status, 'hidden' ) ?> /> <?php _e( 'Hidden', 'buddypress' ) ?></li>
+		<fieldset>
+			<legend><?php _e( 'Privacy', 'buddypress' ); ?></legend>
+
+			<ul>
+				<li><input type="radio" name="group-status" id="bp-group-status-public" value="public" <?php checked( $item->status, 'public' ) ?> /><label for="bp-group-status-public"><?php _e( 'Public', 'buddypress' ) ?></label></li>
+				<li><input type="radio" name="group-status" id="bp-group-status-private" value="private" <?php checked( $item->status, 'private' ) ?> /><label for="bp-group-status-private"><?php _e( 'Private', 'buddypress' ) ?></label></li>
+				<li><input type="radio" name="group-status" id="bp-group-status-hidden" value="hidden" <?php checked( $item->status, 'hidden' ) ?> /><label for="bp-group-status-hidden"><?php _e( 'Hidden', 'buddypress' ) ?></label></li>
+			</ul>
+		</fieldset>
 	</div>
 
 	<div class="bp-groups-settings-section" id="bp-groups-settings-section-invite-status">
-		<label for="group-invite-status"><?php _e( 'Who can invite others to this group?', 'buddypress' ); ?></label>
-
-		<ul>
-			<li><input type="radio" name="group-invite-status" id="bp-group-invite-status-members" value="members" <?php checked( $invite_status, 'members' ) ?> /> <?php _e( 'All group members', 'buddypress' ) ?></li>
-			<li><input type="radio" name="group-invite-status" id="bp-group-invite-status-mods" value="mods" <?php checked( $invite_status, 'mods' ) ?> /> <?php _e( 'Group admins and mods only', 'buddypress' ) ?></li>
-			<li><input type="radio" name="group-invite-status" id="bp-group-invite-status-admins" value="admins" <?php checked( $invite_status, 'admins' ) ?> /> <?php _e( 'Group admins only', 'buddypress' ) ?></li>
-		</ul>
+		<fieldset>
+			<legend><?php _e( 'Who can invite others to this group?', 'buddypress' ); ?></legend>
+
+			<ul>
+				<li><input type="radio" name="group-invite-status" id="bp-group-invite-status-members" value="members" <?php checked( $invite_status, 'members' ) ?> /><label for="bp-group-invite-status-members"><?php _e( 'All group members', 'buddypress' ) ?></label></li>
+				<li><input type="radio" name="group-invite-status" id="bp-group-invite-status-mods" value="mods" <?php checked( $invite_status, 'mods' ) ?> /><label for="bp-group-invite-status-mods"><?php _e( 'Group admins and mods only', 'buddypress' ) ?></label></li>
+				<li><input type="radio" name="group-invite-status" id="bp-group-invite-status-admins" value="admins" <?php checked( $invite_status, 'admins' ) ?> /><label for="bp-group-invite-status-admins"><?php _e( 'Group admins only', 'buddypress' ) ?></label></li>
+			</ul>
+		</fieldset>
 	</div>
 
 <?php
 }
 
 /**
- * Add New Members metabox
+ * Output the markup for a single group's Add New Members metabox.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_groups_admin_edit_metabox_add_new_members( $item ) {
 	?>
 
-	<input name="bp-groups-new-members" id="bp-groups-new-members" class="bp-suggest-user" placeholder="<?php _e( 'Enter a comma-separated list of user logins.', 'buddypress' ) ?>" />
+	<input name="bp-groups-new-members" id="bp-groups-new-members" class="bp-suggest-user" placeholder="<?php esc_attr_e( 'Enter a comma-separated list of user logins.', 'buddypress' ) ?>" />
 	<ul id="bp-groups-new-members-list"></ul>
 	<?php
 }
 
 /**
- * Members metabox
+ * Renders the Members metabox on single group pages.
  *
- * @param BP_Groups_Group $item The BP_Groups_Group object
+ * @since BuddyPress (1.7.0)
  *
- * @since BuddyPress (1.7)
+ * @param BP_Groups_Group $item The BP_Groups_Group object for the current
+ *        group.
  */
 function bp_groups_admin_edit_metabox_members( $item ) {
 	global $members_template;
@@ -842,10 +864,11 @@ function bp_groups_admin_edit_metabox_members( $item ) {
 }
 
 /**
- * Status metabox for the Groups admin edit screen
+ * Renders the Status metabox for the Groups admin edit screen.
  *
- * @param object $item Group item
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @param object $item Information about the currently displayed group.
  */
 function bp_groups_admin_edit_metabox_status( $item ) {
 	$base_url = add_query_arg( array(
@@ -870,7 +893,7 @@ function bp_groups_admin_edit_metabox_status( $item ) {
 }
 
 /**
- * Create pagination links out of a BP_Group_Member_Query
+ * Create pagination links out of a BP_Group_Member_Query.
  *
  * This function is intended to create pagination links for use under the
  * Manage Members section of the Groups Admin Dashboard pages. It is a stopgap
@@ -878,9 +901,11 @@ function bp_groups_admin_edit_metabox_status( $item ) {
  * Plugin authors should not use this function, as it is likely to be
  * deprecated soon.
  *
- * @since BuddyPress (1.8)
- * @param object $query A BP_Group_Member_Query object
- * @param string $member_type member|mod|admin|banned
+ * @since BuddyPress (1.8.0)
+ *
+ * @param BP_Group_Member_Query $query A BP_Group_Member_Query object.
+ * @param string $member_type member|mod|admin|banned.
+ * @return string Pagination links HTML.
  */
 function bp_groups_admin_create_pagination_links( BP_Group_Member_Query $query, $member_type ) {
 	$pagination = '';
@@ -907,8 +932,8 @@ function bp_groups_admin_create_pagination_links( BP_Group_Member_Query $query,
 	$pag_links = paginate_links( array(
 		'base'      => add_query_arg( $qs_key, '%#%', $url_base ),
 		'format'    => '',
-		'prev_text' => __( '&laquo;' ),
-		'next_text' => __( '&raquo;' ),
+		'prev_text' => __( '&laquo;', 'buddypress' ),
+		'next_text' => __( '&raquo;', 'buddypress' ),
 		'total'     => ceil( $query->total_users / $per_page ),
 		'current'   => $page,
 	) );
@@ -927,9 +952,12 @@ function bp_groups_admin_create_pagination_links( BP_Group_Member_Query $query,
 }
 
 /**
- * Match a set of user ids up to a set of usernames
+ * Get a set of usernames corresponding to a set of user IDs.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
+ *
+ * @param array $user_ids Array of user IDs.
+ * @return array Array of user_logins corresponding to $user_ids.
  */
 function bp_groups_admin_get_usernames_from_ids( $user_ids = array() ) {
 
@@ -944,9 +972,9 @@ function bp_groups_admin_get_usernames_from_ids( $user_ids = array() ) {
 }
 
 /**
- * AJAX handler for group member autocomplete requests
+ * AJAX handler for group member autocomplete requests.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 function bp_groups_admin_autocomplete_handler() {
 
@@ -969,19 +997,19 @@ function bp_groups_admin_autocomplete_handler() {
 	$group_members = ! empty( $group_member_query->results ) ? wp_list_pluck( $group_member_query->results, 'ID' ) : array();
 
 	$terms = isset( $_GET['term'] ) ? $_GET['term'] : '';
-	$users = get_users( array(
-		'blog_id'        => false,
-		'search'         => '*' . $terms . '*',
-		'exclude'        => $group_members,
-		'search_columns' => array( 'user_login', 'user_nicename', 'user_email', 'display_name' ),
-		'number'         => 10
+	$users = bp_core_get_users( array(
+		'type'            => 'alphabetical',
+		'search_terms'    => $terms,
+		'exclude'         => $group_members,
+		'per_page'        => 10,
+		'populate_extras' => false
 	) );
 
-	foreach ( (array) $users as $user ) {
+	foreach ( (array) $users['users'] as $user ) {
 		$return[] = array(
 			/* translators: 1: user_login, 2: user_email */
-			'label' => sprintf( __( '%1$s (%2$s)' ), $user->user_login, $user->user_email ),
-			'value' => $user->user_login,
+			'label' => sprintf( __( '%1$s (%2$s)', 'buddypress' ), bp_is_username_compatibility_mode() ? $user->user_login : $user->user_nicename, $user->user_email ),
+			'value' => $user->user_nicename,
 		);
 	}
 
@@ -992,28 +1020,36 @@ add_action( 'wp_ajax_bp_group_admin_member_autocomplete', 'bp_groups_admin_autoc
 /**
  * List table class for the Groups component admin page.
  *
- * @since BuddyPress (1.7)
+ * @since BuddyPress (1.7.0)
  */
 class BP_Groups_List_Table extends WP_List_Table {
 
 	/**
-	 * What type of view is being displayed? e.g. "All", "Pending", "Approved", "Spam"...
+	 * The type of view currently being displayed.
 	 *
-	 * @since BuddyPress (1.7)
-	*/
+	 * e.g. "All", "Pending", "Approved", "Spam"...
+	 *
+	 * @since BuddyPress (1.7.0)
+	 *
+	 * @access public
+	 * @var string
+	 */
 	public $view = 'all';
 
 	/**
-	 * Group counts for each group type
+	 * Group counts for each group type.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @since BuddyPress (1.7)
+	 * @access public
+	 * @var int
 	 */
 	public $group_counts = 0;
 
 	/**
 	 * Constructor
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __construct() {
 
@@ -1026,9 +1062,12 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Handle filtering of data, sorting, pagination, and any other data-manipulation required prior to rendering.
+	 * Set up items for display in the list table.
 	 *
-	 * @since BuddyPress (1.7)
+	 * Handles filtering of data, sorting, pagination, and any other data
+	 * manipulation required prior to rendering.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 */
 	function prepare_items() {
 		global $groups_template;
@@ -1131,10 +1170,11 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Get an array of all the columns on the page
+	 * Get an array of all the columns on the page.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @return array
-	 * @since BuddyPress (1.7)
+	 * @return array Array of column headers.
 	 */
 	function get_column_info() {
 		$this->_column_headers = array(
@@ -1147,18 +1187,18 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Displays a message on screen when no items are found (e.g. no search matches)
+	 * Display a message on screen when no items are found ("No groups found").
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	function no_items() {
 		_e( 'No groups found.', 'buddypress' );
 	}
 
 	/**
-	 * Outputs the Groups data table
+	 * Output the Groups data table.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	*/
 	function display() {
 		extract( $this->_args );
@@ -1188,38 +1228,46 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Generates content for a single row of the table
+	 * Generate content for a single row of the table.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @param object $item The current item
-	 * @since BuddyPress (1.7)
+	 * @param object $item The current group item in the loop.
 	 */
 	function single_row( $item = array() ) {
-		static $row_class = '';
+		static $even = false;
 
-		if ( empty( $row_class ) ) {
-			$row_class = ' class="alternate odd"';
+		$row_classes = array();
+
+		if ( $even ) {
+			$row_classes = array( 'even' );
 		} else {
-			$row_class = ' class="even"';
+			$row_classes = array( 'alternate', 'odd' );
 		}
 
+		$row_classes = apply_filters( 'bp_groups_admin_row_class', $row_classes, $item['id'] );
+		$row_class = ' class="' . implode( ' ', $row_classes ) . '"';
+
 		echo '<tr' . $row_class . ' id="group-' . esc_attr( $item['id'] ) . '" data-parent_id="' . esc_attr( $item['id'] ) . '" data-root_id="' . esc_attr( $item['id'] ) . '">';
 		echo $this->single_row_columns( $item );
 		echo '</tr>';
+
+		$even = ! $even;
 	}
 
 	/**
 	 * Get the list of views available on this table (e.g. "all", "public").
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	function get_views() {
 		$url_base = bp_get_admin_url( 'admin.php?page=bp-groups' ); ?>
 
 		<ul class="subsubsub">
 			<li class="all"><a href="<?php echo esc_attr( esc_url( $url_base ) ); ?>" class="<?php if ( 'all' == $this->view ) echo 'current'; ?>"><?php _e( 'All', 'buddypress' ); ?></a> |</li>
-			<li class="public"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'public', $url_base ) ) ); ?>" class="<?php if ( 'public' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Public <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->group_counts['public'] ) ); ?></a> |</li>
-			<li class="private"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'private', $url_base ) ) ); ?>" class="<?php if ( 'private' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Private <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->group_counts['private'] ) ); ?></a> |</li>
-			<li class="hidden"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'hidden', $url_base ) ) ); ?>" class="<?php if ( 'hidden' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Hidden <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->group_counts['hidden'] ) ); ?></a></li>
+			<li class="public"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'public', $url_base ) ) ); ?>" class="<?php if ( 'public' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Public <span class="count">(%s)</span>', 'Public <span class="count">(%s)</span>', $this->group_counts['public'], 'buddypress' ), number_format_i18n( $this->group_counts['public'] ) ); ?></a> |</li>
+			<li class="private"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'private', $url_base ) ) ); ?>" class="<?php if ( 'private' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>', $this->group_counts['private'], 'buddypress' ), number_format_i18n( $this->group_counts['private'] ) ); ?></a> |</li>
+			<li class="hidden"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'hidden', $url_base ) ) ); ?>" class="<?php if ( 'hidden' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Hidden <span class="count">(%s)</span>', 'Hidden <span class="count">(%s)</span>', $this->group_counts['hidden'], 'buddypress' ), number_format_i18n( $this->group_counts['hidden'] ) ); ?></a></li>
 
 			<?php do_action( 'bp_groups_list_table_get_views', $url_base, $this->view ); ?>
 		</ul>
@@ -1227,10 +1275,11 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Get bulk actions
+	 * Get bulk actions for single group row.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @return array Key/value pairs for the bulk actions dropdown
-	 * @since BuddyPress (1.7)
+	 * @return array Key/value pairs for the bulk actions dropdown.
 	 */
 	function get_bulk_actions() {
 		return apply_filters( 'bp_groups_list_table_get_bulk_actions', array(
@@ -1241,19 +1290,21 @@ class BP_Groups_List_Table extends WP_List_Table {
 	/**
 	 * Get the table column titles.
 	 *
+	 * @since BuddyPress (1.7.0)
+	 *
 	 * @see WP_List_Table::single_row_columns()
-	 * @return array
-	 * @since BuddyPress (1.7)
+	 *
+	 * @return array Array of column titles.
 	 */
 	function get_columns() {
-		return array(
+		return apply_filters( 'bp_groups_list_table_get_columns', array(
 			'cb'          => '<input name type="checkbox" />',
 			'comment'     => _x( 'Name', 'Groups admin Group Name column header',               'buddypress' ),
 			'description' => _x( 'Description', 'Groups admin Group Description column header', 'buddypress' ),
 			'status'      => _x( 'Status', 'Groups admin Privacy Status column header',         'buddypress' ),
 			'members'     => _x( '# Members', 'Groups admin Members column header',             'buddypress' ),
 			'last_active' => _x( 'Last Active', 'Groups admin Last Active column header',       'buddypress' )
-		);
+		) );
 	}
 
 	/**
@@ -1268,8 +1319,9 @@ class BP_Groups_List_Table extends WP_List_Table {
 	 * the sort order - ie, to make it ASC. Thus last_active is set to
 	 * $desc_first = false.
 	 *
-	 * @return array
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
+	 *
+	 * @return array Array of sortable column names.
 	 */
 	function get_sortable_columns() {
 		return array(
@@ -1281,22 +1333,26 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Checkbox column
+	 * Markup for the Checkbox column.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @param array $item A singular item (one full row)
 	 * @see WP_List_Table::single_row_columns()
-	 * @since BuddyPress (1.7)
+	 *
+	 * @param array $item A singular item (one full row).
 	 */
 	function column_cb( $item = array() ) {
-		printf( '<label class="screen-reader-text" for="aid-%1$d">' . __( 'Select group %1$d', 'buddypress' ) . '</label><input type="checkbox" name="aid[]" value="%1$d" id="aid-%1$d" />', $item['id'] );
+		printf( '<label class="screen-reader-text" for="gid-%1$d">' . __( 'Select group %1$d', 'buddypress' ) . '</label><input type="checkbox" name="gid[]" value="%1$d" id="gid-%1$d" />', $item['id'] );
 	}
 
 	/**
-	 * Group id column
+	 * Markup for the Group ID column.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @param array $item A singular item (one full row)
 	 * @see WP_List_Table::single_row_columns()
-	 * @since BuddyPress (1.7)
+	 *
+	 * @param array $item A singular item (one full row).
 	 */
 	function column_gid( $item = array() ) {
 		echo '<strong>' . $item['id'] . '</strong>';
@@ -1307,9 +1363,11 @@ class BP_Groups_List_Table extends WP_List_Table {
 	 *
 	 * Called "comment" in the CSS so we can re-use some WP core CSS.
 	 *
-	 * @param array $item A singular item (one full row)
+	 * @since BuddyPress (1.7.0)
+	 *
 	 * @see WP_List_Table::single_row_columns()
-	 * @since BuddyPress (1.7)
+	 *
+	 * @param array $item A singular item (one full row).
 	 */
 	function column_comment( $item = array() ) {
 
@@ -1361,18 +1419,22 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Description column
+	 * Markup for the Description column.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @since BuddyPress (1.7)
+	 * @param array Information about the current row.
 	 */
 	function column_description( $item = array() ) {
 		echo apply_filters_ref_array( 'bp_get_group_description', array( $item['description'], $item ) );
 	}
 
 	/**
-	 * Status column
+	 * Markup for the Status column.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
+	 *
+	 * @param array Information about the current row.
 	 */
 	function column_status( $item = array() ) {
 		$status      = $item['status'];
@@ -1396,9 +1458,11 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Number of Members column
+	 * Markup for the Number of Members column.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @since BuddyPress (1.7)
+	 * @param array Information about the current row.
 	 */
 	function column_members( $item = array() ) {
 		$count = groups_get_groupmeta( $item['id'], 'total_member_count' );
@@ -1406,12 +1470,26 @@ class BP_Groups_List_Table extends WP_List_Table {
 	}
 
 	/**
-	 * Last Active column
+	 * Markup for the Last Active column.
+	 *
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @since BuddyPress (1.7)
+	 * @param array Information about the current row.
 	 */
 	function column_last_active( $item = array() ) {
 		$last_active = groups_get_groupmeta( $item['id'], 'last_activity' );
 		echo apply_filters_ref_array( 'bp_groups_admin_get_group_last_active', array( $last_active, $item ) );
 	}
+
+	/**
+	 * Allow plugins to add their costum column.
+	 *
+	 * @since BuddyPress 2.0.0
+	 *
+	 * @param array Information about the current row.
+	 * @param string the column name.
+	 */
+	function column_default( $item = array(), $column_name = '' ) {
+		return apply_filters( 'bp_groups_admin_get_group_custom_column', '', $column_name, $item );
+	}
 }
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-adminbar.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-adminbar.php
index 02cc795df49e53e25ff8c833f1e079c45551ad42..d9c67605e5dacaec70834d2e01b74cbb76711abf 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-adminbar.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-adminbar.php
@@ -3,7 +3,7 @@
 /**
  * BuddyPress Groups Toolbar
  *
- * Handles the groups functions related to the WordPress Toolbar
+ * Handles the groups functions related to the WordPress Toolbar.
  *
  * @package BuddyPress
  * @subpackage Groups
@@ -13,12 +13,11 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Adds the Group Admin top-level menu to group pages
+ * Add the Group Admin top-level menu when viewing group pages.
  *
- * @package BuddyPress
- * @since BuddyPress (1.5)
+ * @since BuddyPress (1.5.0)
  *
- * @todo Add dynamic menu items for group extensions
+ * @todo Add dynamic menu items for group extensions.
  */
 function bp_groups_group_admin_menu() {
 	global $wp_admin_bar, $bp;
@@ -106,13 +105,13 @@ function bp_groups_group_admin_menu() {
 add_action( 'admin_bar_menu', 'bp_groups_group_admin_menu', 99 );
 
 /**
- * Remove rogue WP core edit menu when viewing a group
+ * Remove rogue WP core Edit menu when viewing a single group.
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 function bp_groups_remove_edit_page_menu() {
 	if ( bp_is_group() ) {
 		remove_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 80 );
 	}
 }
-add_action( 'bp_init', 'bp_groups_remove_edit_page_menu', 99 );
+add_action( 'add_admin_bar_menus', 'bp_groups_remove_edit_page_menu' );
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-buddybar.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-buddybar.php
index db88d28371213d848b10e53a06241ead80fdbf3d..6ce1764137bc9119c6e56df010fd2cd83830b87e 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-buddybar.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-buddybar.php
@@ -11,9 +11,10 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Adds menu items to the BuddyBar
+ * Add menu items to the BuddyBar.
+ *
+ * @since BuddyPress (1.0.0)
  *
- * @since BuddyPress (1.0)
  * @global BuddyPress $bp
  */
 function bp_groups_adminbar_admin_menu() {
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-cache.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-cache.php
index 9a86688dae2d456a5074dfa7afa8b72a2c8a3261..cbd9ac9c7eb31a833204242d73c03d9b3ab3372c 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-cache.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-cache.php
@@ -14,17 +14,18 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
- * Slurps up groupmeta
+ * Slurp up metadata for a set of groups.
  *
  * This function is called in two places in the BP_Groups_Group class:
  *   - in the populate() method, when single group objects are populated
  *   - in the get() method, when multiple groups are queried
  *
- * It grabs all groupmeta associated with all of the groups passed in $group_ids and adds it to
- * the WP cache. This improves efficiency when using groupmeta inline
+ * It grabs all groupmeta associated with all of the groups passed in
+ * $group_ids and adds it to WP cache. This improves efficiency when using
+ * groupmeta within a loop context.
  *
- * @param int|str|array $group_ids Accepts a single group_id, or a comma-separated list or array of
- *    group ids
+ * @param int|str|array $group_ids Accepts a single group_id, or a
+ *        comma-separated list or array of group ids.
  */
 function bp_groups_update_meta_cache( $group_ids = false ) {
 	global $bp;
@@ -32,6 +33,7 @@ function bp_groups_update_meta_cache( $group_ids = false ) {
 	$cache_args = array(
 		'object_ids' 	   => $group_ids,
 		'object_type' 	   => $bp->groups->id,
+		'cache_group'      => 'group_meta',
 		'object_column'    => 'group_id',
 		'meta_table' 	   => $bp->groups->table_name_groupmeta,
 		'cache_key_prefix' => 'bp_groups_groupmeta'
@@ -40,6 +42,11 @@ function bp_groups_update_meta_cache( $group_ids = false ) {
 	bp_update_meta_cache( $cache_args );
 }
 
+/**
+ * Clear the cached group count.
+ *
+ * @param $group_id Not used.
+ */
 function groups_clear_group_object_cache( $group_id ) {
 	wp_cache_delete( 'bp_total_group_count', 'bp' );
 }
@@ -50,14 +57,14 @@ add_action( 'groups_group_avatar_updated',       'groups_clear_group_object_cach
 add_action( 'groups_create_group_step_complete', 'groups_clear_group_object_cache' );
 
 /**
- * Bust group caches when editing or deleting
+ * Bust group caches when editing or deleting.
  *
- * @since BuddyPress (1.7)
- * @param int $group_id The group being edited
+ * @since BuddyPress (1.7.0)
+ *
+ * @param int $group_id The group being edited.
  */
 function bp_groups_delete_group_cache( $group_id = 0 ) {
-	wp_cache_delete( 'bp_groups_group_' . $group_id . '_load_users', 'bp' );
-	wp_cache_delete( 'bp_groups_group_' . $group_id . '_noload_users', 'bp' );
+	wp_cache_delete( $group_id, 'bp_groups' );
 }
 add_action( 'groups_delete_group',     'bp_groups_delete_group_cache' );
 add_action( 'groups_update_group',     'bp_groups_delete_group_cache' );
@@ -65,11 +72,23 @@ add_action( 'groups_details_updated',  'bp_groups_delete_group_cache' );
 add_action( 'groups_settings_updated', 'bp_groups_delete_group_cache' );
 
 /**
- * Clears caches for the group creator when a group is created
+ * Bust group cache when modifying metadata.
  *
- * @param int $group_id
- * @param BP_Groups_Group $group_obj
- * @since BuddyPress (1.6)
+ * @since BuddyPress (2.0.0)
+ */
+function bp_groups_delete_group_cache_on_metadata_change( $meta_id, $group_id ) {
+	wp_cache_delete( $group_id, 'bp_groups' );
+}
+add_action( 'updated_group_meta', 'bp_groups_delete_group_cache_on_metadata_change', 10, 2 );
+add_action( 'added_group_meta', 'bp_groups_delete_group_cache_on_metadata_change', 10, 2 );
+
+/**
+ * Clear caches for the group creator when a group is created.
+ *
+ * @since BuddyPress (1.6.0)
+ *
+ * @param int $group_id ID of the group.
+ * @param BP_Groups_Group $group_obj Group object.
  */
 function bp_groups_clear_group_creator_cache( $group_id, $group_obj ) {
 	// Clears the 'total groups' for this user
@@ -80,9 +99,10 @@ add_action( 'groups_created_group', 'bp_groups_clear_group_creator_cache', 10, 2
 /**
  * Clears caches for all members in a group when a group is deleted
  *
- * @param BP_Groups_Group $group_obj
- * @param array User IDs who were in this group
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
+ *
+ * @param BP_Groups_Group $group_obj Group object.
+ * @param array User IDs who were in this group.
  */
 function bp_groups_clear_group_members_caches( $group_obj, $user_ids ) {
 	// Clears the 'total groups' cache for each member in a group
@@ -91,6 +111,58 @@ function bp_groups_clear_group_members_caches( $group_obj, $user_ids ) {
 }
 add_action( 'bp_groups_delete_group', 'bp_groups_clear_group_members_caches', 10, 2 );
 
+/**
+ * Clear a user's cached total group invite count.
+ *
+ * Count is cleared when an invite is accepted, rejected or deleted.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $user_id The user ID.
+ */
+function bp_groups_clear_invite_count_for_user( $user_id ) {
+	wp_cache_delete( $user_id, 'bp_group_invite_count' );
+}
+add_action( 'groups_accept_invite', 'bp_groups_clear_invite_count_for_user' );
+add_action( 'groups_reject_invite', 'bp_groups_clear_invite_count_for_user' );
+add_action( 'groups_delete_invite', 'bp_groups_clear_invite_count_for_user' );
+
+/**
+ * Clear a user's cached total group invite count when a user is uninvited.
+ *
+ * Groan. Our API functions are not consistent.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $group_id The group ID. Not used in this function.
+ * @param int $user_id The user ID.
+ */
+function bp_groups_clear_invite_count_on_uninvite( $group_id, $user_id ) {
+	bp_groups_clear_invite_count_for_user( $user_id );
+}
+add_action( 'groups_uninvite_user', 'bp_groups_clear_invite_count_on_uninvite', 10, 2 );
+
+/**
+ * Clear a user's cached total group invite count when a new invite is sent.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $group_id The group ID. Not used in this function.
+ * @param array $invited_users Array of invited user IDs.
+ */
+function bp_groups_clear_invite_count_on_send( $group_id, $invited_users ) {
+	foreach ( $invited_users as $user_id ) {
+		bp_groups_clear_invite_count_for_user( $user_id );
+	}
+}
+add_action( 'groups_send_invites', 'bp_groups_clear_invite_count_on_send', 10, 2 );
+
+/**
+ * Clear a user's cached group count.
+ *
+ * @param int $group_id The group ID. Not used in this function.
+ * @param int $user_id The user ID.
+ */
 function groups_clear_group_user_object_cache( $group_id, $user_id ) {
 	wp_cache_delete( 'bp_total_groups_for_user_' . $user_id, 'bp' );
 }
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-classes.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-classes.php
index b329829c1b7bd36f9a4643a2f3721cd4026ed4e6..c036b62ea5e6a45413aa7db3e29abce40cfaf8dd 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-classes.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-classes.php
@@ -10,32 +10,129 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * BuddyPress Group object.
+ */
 class BP_Groups_Group {
-	var $id;
-	var $creator_id;
-	var $name;
-	var $slug;
-	var $description;
-	var $status;
-	var $enable_forum;
-	var $date_created;
 
-	var $admins;
-	var $mods;
-	var $total_member_count;
+	/**
+	 * ID of the group.
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $id;
+
+	/**
+	 * User ID of the group's creator.
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $creator_id;
+
+	/**
+	 * Name of the group.
+	 *
+	 * @access public
+	 * @var string
+	 */
+	public $name;
+
+	/**
+	 * Group slug.
+	 *
+	 * @access public
+	 * @var string
+	 */
+	public $slug;
+
+	/**
+	 * Group description.
+	 *
+	 * @access public
+	 * @var string
+	 */
+	public $description;
+
+	/**
+	 * Group status.
+	 *
+	 * Core statuses are 'public', 'private', and 'hidden'.
+	 *
+	 * @access public
+	 * @var string
+	 */
+	public $status;
+
+	/**
+	 * Should (legacy) bbPress forums be enabled for this group?
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $enable_forum;
+
+	/**
+	 * Date the group was created.
+	 *
+	 * @access public
+	 * @var string
+	 */
+	public $date_created;
+
+	/**
+	 * Data about the group's admins.
+	 *
+	 * @access public
+	 * @var array
+	 */
+	public $admins;
+
+	/**
+	 * Data about the group's moderators.
+	 *
+	 * @access public
+	 * @var array
+	 */
+	public $mods;
+
+	/**
+	 * Total count of group members.
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $total_member_count;
 
 	/**
 	 * Is the current user a member of this group?
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var bool
 	 */
 	public $is_member;
 
+	/**
+	 * Does the current user have an outstanding invitation to this group?
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @var bool
+	 */
+	public $is_invited;
+
+	/**
+	 * Does the current user have a pending membership request to this group?
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @var bool
+	 */
+	public $is_pending;
+
 	/**
 	 * Timestamp of the last activity that happened in this group.
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var string
 	 */
 	public $last_activity;
@@ -43,60 +140,119 @@ class BP_Groups_Group {
 	/**
 	 * If this is a private or hidden group, does the current user have access?
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 * @var bool
 	 */
 	public $user_has_access;
 
-	function __construct( $id = null ) {
+	/**
+	 * Raw arguments passed to the constructor.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 * @var array
+	 */
+	public $args;
+
+	/**
+	 * Constructor method.
+	 *
+	 * @param int $id Optional. If the ID of an existing group is provided,
+	 *        the object will be pre-populated with info about that group.
+	 */
+	public function __construct( $id = null, $args = array() ) {
+		$this->args = wp_parse_args( $args, array(
+			'populate_extras' => false,
+		) );
+
 		if ( !empty( $id ) ) {
 			$this->id = $id;
 			$this->populate();
 		}
 	}
 
-	function populate() {
-		global $wpdb, $bp;
+	/**
+	 * Set up data about the current group.
+	 */
+	public function populate() {
+		global $wpdb;
+
+		// Get BuddyPress
+		$bp    = buddypress();
+
+		// Check cache for group data
+		$group = wp_cache_get( $this->id, 'bp_groups' );
+
+		// Cache missed, so query the DB
+		if ( false === $group ) {
+			$group = $wpdb->get_row( $wpdb->prepare( "SELECT g.* FROM {$bp->groups->table_name} g WHERE g.id = %d", $this->id ) );
+
+			wp_cache_set( $this->id, $group, 'bp_groups' );
+		}
+
+		// No group found so set the ID and bail
+		if ( empty( $group ) || is_wp_error( $group ) ) {
+			$this->id = 0;
+			return;
+		}
+
+		// Group found so setup the object variables
+		$this->id           = $group->id;
+		$this->creator_id   = $group->creator_id;
+		$this->name         = stripslashes( $group->name );
+		$this->slug         = $group->slug;
+		$this->description  = stripslashes( $group->description );
+		$this->status       = $group->status;
+		$this->enable_forum = $group->enable_forum;
+		$this->date_created = $group->date_created;
+
+		// Are we getting extra group data?
+		if ( ! empty( $this->args['populate_extras'] ) ) {
+
+			// Get group admins and mods
+			$admin_mods = $wpdb->get_results( apply_filters( 'bp_group_admin_mods_user_join_filter', $wpdb->prepare( "SELECT u.ID as user_id, u.user_login, u.user_email, u.user_nicename, m.is_admin, m.is_mod FROM {$wpdb->users} u, {$bp->groups->table_name_members} m WHERE u.ID = m.user_id AND m.group_id = %d AND ( m.is_admin = 1 OR m.is_mod = 1 )", $this->id ) ) );
+
+			// Add admins and moderators to their respective arrays
+			foreach ( (array) $admin_mods as $user ) {
+				if ( !empty( $user->is_admin ) ) {
+					$this->admins[] = $user;
+				} else {
+					$this->mods[] = $user;
+				}
+			}
 
-		if ( $group = $wpdb->get_row( $wpdb->prepare( "SELECT g.* FROM {$bp->groups->table_name} g WHERE g.id = %d", $this->id ) ) ) {
-			bp_groups_update_meta_cache( $this->id );
-
-			$this->id                 = $group->id;
-			$this->creator_id         = $group->creator_id;
-			$this->name               = stripslashes($group->name);
-			$this->slug               = $group->slug;
-			$this->description        = stripslashes($group->description);
-			$this->status             = $group->status;
-			$this->enable_forum       = $group->enable_forum;
-			$this->date_created       = $group->date_created;
+			// Set up some specific group vars from meta. Excluded
+			// from the bp_groups cache because it's cached independently
 			$this->last_activity      = groups_get_groupmeta( $this->id, 'last_activity' );
 			$this->total_member_count = groups_get_groupmeta( $this->id, 'total_member_count' );
-			$this->is_member          = BP_Groups_Member::check_is_member( bp_loggedin_user_id(), $this->id );
+
+			// Set user-specific data
+			$user_id          = bp_loggedin_user_id();
+			$this->is_member  = BP_Groups_Member::check_is_member( $user_id, $this->id );
+			$this->is_invited = BP_Groups_Member::check_has_invite( $user_id, $this->id );
+			$this->is_pending = BP_Groups_Member::check_for_membership_request( $user_id, $this->id );
 
 			// If this is a private or hidden group, does the current user have access?
-			if ( 'private' == $this->status || 'hidden' == $this->status ) {
-				if ( $this->is_member && is_user_logged_in() || bp_current_user_can( 'bp_moderate' ) )
+			if ( ( 'private' === $this->status ) || ( 'hidden' === $this->status ) ) {
+
+				// Assume user does not have access to hidden/private groups
+				$this->user_has_access = false;
+
+				// Group members or community moderators have access
+				if ( ( $this->is_member && is_user_logged_in() ) || bp_current_user_can( 'bp_moderate' ) ) {
 					$this->user_has_access = true;
-				else
-					$this->user_has_access = false;
+				}
 			} else {
 				$this->user_has_access = true;
 			}
-
-			// Get group admins and mods
-			$admin_mods = $wpdb->get_results( apply_filters( 'bp_group_admin_mods_user_join_filter', $wpdb->prepare( "SELECT u.ID as user_id, u.user_login, u.user_email, u.user_nicename, m.is_admin, m.is_mod FROM {$wpdb->users} u, {$bp->groups->table_name_members} m WHERE u.ID = m.user_id AND m.group_id = %d AND ( m.is_admin = 1 OR m.is_mod = 1 )", $this->id ) ) );
-			foreach( (array) $admin_mods as $user ) {
-				if ( (int) $user->is_admin )
-					$this->admins[] = $user;
-				else
-					$this->mods[] = $user;
-			}
-		} else {
-			$this->id = 0;
 		}
 	}
 
-	function save() {
+	/**
+	 * Save the current group to the database.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function save() {
 		global $wpdb, $bp;
 
 		$this->creator_id   = apply_filters( 'groups_group_creator_id_before_save',   $this->creator_id,   $this->id );
@@ -109,6 +265,26 @@ class BP_Groups_Group {
 
 		do_action_ref_array( 'groups_group_before_save', array( &$this ) );
 
+		// Groups need at least a name
+		if ( empty( $this->name ) ) {
+			return false;
+		}
+
+		// Set slug with group title if not passed
+		if ( empty( $this->slug ) ) {
+			$this->slug = sanitize_title( $this->name );
+		}
+
+		// Sanity check
+		if ( empty( $this->slug ) ) {
+			return false;
+		}
+
+		// Check for slug conflicts if creating new group
+		if ( empty( $this->id ) ) {
+			$this->slug = groups_check_slug( $this->slug );
+		}
+
 		if ( !empty( $this->id ) ) {
 			$sql = $wpdb->prepare(
 				"UPDATE {$bp->groups->table_name} SET
@@ -162,12 +338,17 @@ class BP_Groups_Group {
 
 		do_action_ref_array( 'groups_group_after_save', array( &$this ) );
 
-		wp_cache_delete( 'bp_groups_group_' . $this->id, 'bp' );
+		wp_cache_delete( $this->id, 'bp_groups' );
 
 		return true;
 	}
 
-	function delete() {
+	/**
+	 * Delete the current group.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function delete() {
 		global $wpdb, $bp;
 
 		// Delete groupmeta for the group
@@ -185,7 +366,7 @@ class BP_Groups_Group {
 
 		do_action_ref_array( 'bp_groups_delete_group', array( &$this, $user_ids ) );
 
-		wp_cache_delete( 'bp_groups_group_' . $this->id, 'bp' );
+		wp_cache_delete( $this->id, 'bp_groups' );
 
 		// Finally remove the group entry from the DB
 		if ( !$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name} WHERE id = %d", $this->id ) ) )
@@ -194,9 +375,17 @@ class BP_Groups_Group {
 		return true;
 	}
 
-	/** Static Methods ********************************************************/
+	/** Static Methods ****************************************************/
 
-	function group_exists( $slug, $table_name = false ) {
+	/**
+	 * Get whether a group exists for a given slug.
+	 *
+	 * @param string $slug Slug to check.
+	 * @param string $table_name Optional. Name of the table to check
+	 *        against. Default: $bp->groups->table_name.
+	 * @return string|null ID of the group, if one is found, else null.
+	 */
+	public static function group_exists( $slug, $table_name = false ) {
 		global $wpdb, $bp;
 
 		if ( empty( $table_name ) )
@@ -205,19 +394,52 @@ class BP_Groups_Group {
 		if ( empty( $slug ) )
 			return false;
 
-		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$table_name} WHERE slug = %s", $slug ) );
+		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$table_name} WHERE slug = %s", strtolower( $slug ) ) );
 	}
 
-	function get_id_from_slug( $slug ) {
+	/**
+	 * Get the ID of a group by the group's slug.
+	 *
+	 * Alias of {@link BP_Groups_Group::group_exists()}.
+	 *
+	 * @param string $slug See {@link BP_Groups_Group::group_exists()}.
+	 * @return string|null See {@link BP_Groups_Group::group_exists()}.
+	 */
+	public static function get_id_from_slug( $slug ) {
 		return BP_Groups_Group::group_exists( $slug );
 	}
 
-	function get_invites( $user_id, $group_id ) {
+	/**
+	 * Get IDs of users with outstanding invites to a given group from a specified user.
+	 *
+	 * @param int $user_id ID of the inviting user.
+	 * @param int $group_id ID of the group.
+	 * @return array IDs of users who have been invited to the group by the
+	 *         user but have not yet accepted.
+	 */
+	public static function get_invites( $user_id, $group_id ) {
 		global $wpdb, $bp;
 		return $wpdb->get_col( $wpdb->prepare( "SELECT user_id FROM {$bp->groups->table_name_members} WHERE group_id = %d and is_confirmed = 0 AND inviter_id = %d", $group_id, $user_id ) );
 	}
 
-	function filter_user_groups( $filter, $user_id = 0, $order = false, $limit = null, $page = null ) {
+	/**
+	 * Get a list of a user's groups, filtered by a search string.
+	 *
+	 * @param string $filter Search term. Matches against 'name' and
+	 *        'description' fields.
+	 * @param int $user_id ID of the user whose groups are being searched.
+	 *        Default: the displayed user.
+	 * @param mixed $order Not used.
+	 * @param int $limit Optional. The max number of results to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page offset of results to return.
+	 *        Default: null (no limit).
+	 * @return array {
+	 *     @type array $groups Array of matched and paginated group objects.
+	 *     @type int $total Total count of groups matching the query.
+	 * }
+	 */
+	public static function filter_user_groups( $filter, $user_id = 0, $order = false, $limit = null, $page = null ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -225,6 +447,8 @@ class BP_Groups_Group {
 
 		$filter = esc_sql( like_escape( $filter ) );
 
+		$pag_sql = $order_sql = $hidden_sql = '';
+
 		if ( !empty( $limit ) && !empty( $page ) )
 			$pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
 
@@ -243,13 +467,29 @@ class BP_Groups_Group {
 	}
 
 	/**
-	 * @todo Deprecate in favor of get()
+	 * Get a list of groups, filtered by a search string.
+	 *
+	 * @param string $filter Search term. Matches against 'name' and
+	 *        'description' fields.
+	 * @param int $limit Optional. The max number of results to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page offset of results to return.
+	 *        Default: null (no limit).
+	 * @param string $sort_by Column to sort by. Default: false (default
+	 *        sort).
+	 * @param string $order ASC or DESC. Default: false (default sort).
+	 * @return array {
+	 *     @type array $groups Array of matched and paginated group objects.
+	 *     @type int $total Total count of groups matching the query.
+	 * }
 	 */
-	function search_groups( $filter, $limit = null, $page = null, $sort_by = false, $order = false ) {
+	public static function search_groups( $filter, $limit = null, $page = null, $sort_by = false, $order = false ) {
 		global $wpdb, $bp;
 
 		$filter = esc_sql( like_escape( $filter ) );
 
+		$pag_sql = $order_sql = $hidden_sql = '';
+
 		if ( !empty( $limit ) && !empty( $page ) )
 			$pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
 
@@ -268,19 +508,37 @@ class BP_Groups_Group {
 		return array( 'groups' => $paged_groups, 'total' => $total_groups );
 	}
 
-	function check_slug( $slug ) {
+	/**
+	 * Check for the existence of a slug.
+	 *
+	 * @param string $slug Slug to check.
+	 * @return string|null The slug, if found. Otherwise null.
+	 */
+	public static function check_slug( $slug ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM {$bp->groups->table_name} WHERE slug = %s", $slug ) );
 	}
 
-	function get_slug( $group_id ) {
+	/**
+	 * Get the slug for a given group ID.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return string|null The slug, if found. Otherwise null.
+	 */
+	public static function get_slug( $group_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM {$bp->groups->table_name} WHERE id = %d", $group_id ) );
 	}
 
-	function has_members( $group_id ) {
+	/**
+	 * Check whether a given group has any members.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return bool True if the group has members, otherwise false.
+	 */
+	public static function has_members( $group_id ) {
 		global $wpdb, $bp;
 
 		$members = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->groups->table_name_members} WHERE group_id = %d", $group_id ) );
@@ -291,13 +549,34 @@ class BP_Groups_Group {
 		return true;
 	}
 
-	function has_membership_requests( $group_id ) {
+	/**
+	 * Check whether a group has outstanding membership requests.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return int|null The number of outstanding requests, or null if
+	 *         none are found.
+	 */
+	public static function has_membership_requests( $group_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 0", $group_id ) );
 	}
 
-	function get_membership_requests( $group_id, $limit = null, $page = null ) {
+	/**
+	 * Get outstanding membership requests for a group.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @param int $limit Optional. Max number of results to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. Page offset of results returned. Default:
+	 *        null (no limit).
+	 * @return array {
+	 *     @type array $requests The requested page of located requests.
+	 *     @type int $total Total number of requests outstanding for the
+	 *           group.
+	 * }
+	 */
+	public static function get_membership_requests( $group_id, $limit = null, $page = null ) {
 		global $wpdb, $bp;
 
 		if ( !empty( $limit ) && !empty( $page ) ) {
@@ -310,7 +589,56 @@ class BP_Groups_Group {
 		return array( 'requests' => $paged_requests, 'total' => $total_requests );
 	}
 
-	function get( $args = array() ) {
+	/**
+	 * Query for groups.
+	 *
+	 * @see WP_Meta_Query::queries for a description of the 'meta_query'
+	 *      parameter format.
+	 *
+	 * @param array {
+	 *     Array of parameters. All items are optional.
+	 *     @type string $type Optional. Shorthand for certain orderby/
+	 *           order combinations. 'newest', 'active', 'popular',
+	 *           'alphabetical', 'random'. When present, will override
+	 *           orderby and order params. Default: null.
+	 *     @type string $orderby Optional. Property to sort by.
+	 *           'date_created', 'last_activity', 'total_member_count',
+	 *           'name', 'random'. Default: 'date_created'.
+	 *     @type string $order Optional. Sort order. 'ASC' or 'DESC'.
+	 *           Default: 'DESC'.
+	 *     @type int $per_page Optional. Number of items to return per page
+	 *           of results. Default: null (no limit).
+	 *     @type int $page Optional. Page offset of results to return.
+	 *           Default: null (no limit).
+	 *     @type int $user_id Optional. If provided, results will be limited
+	 *           to groups of which the specified user is a member. Default:
+	 *           null.
+	 *     @type string $search_terms Optional. If provided, only groups
+	 *           whose names or descriptions match the search terms will be
+	 *           returned. Default: false.
+	 *     @type array $meta_query Optional. An array of meta_query
+	 *           conditions. See {@link WP_Meta_Query::queries} for
+	 *           description.
+	 *     @type array|string Optional. Array or comma-separated list of
+	 *           group IDs. Results will be limited to groups within the
+	 *           list. Default: false.
+	 *     @type bool $populate_extras Whether to fetch additional
+	 *           information (such as member count) about groups. Default:
+	 *           true.
+	 *     @type array|string Optional. Array or comma-separated list of
+	 *           group IDs. Results will exclude the listed groups.
+	 *           Default: false.
+	 *     @type bool $show_hidden Whether to include hidden groups in
+	 *           results. Default: false.
+	 * }
+	 * @return array {
+	 *     @type array $groups Array of group objects returned by the
+	 *           paginated query.
+	 *     @type int $total Total count of all groups matching non-
+	 *           paginated query params.
+	 * }
+	 */
+	public static function get( $args = array() ) {
 		global $wpdb, $bp;
 
 		// Backward compatibility with old method of passing arguments
@@ -334,18 +662,19 @@ class BP_Groups_Group {
 		}
 
 		$defaults = array(
-			'type'            => null,
-			'orderby'         => 'date_created',
-			'order'           => 'DESC',
-			'per_page'        => null,
-			'page'            => null,
-			'user_id'         => 0,
-			'search_terms'    => false,
-			'meta_query'      => false,
-			'include'         => false,
-			'populate_extras' => true,
-			'exclude'         => false,
-			'show_hidden'     => false,
+			'type'              => null,
+			'orderby'           => 'date_created',
+			'order'             => 'DESC',
+			'per_page'          => null,
+			'page'              => null,
+			'user_id'           => 0,
+			'search_terms'      => false,
+			'meta_query'        => false,
+			'include'           => false,
+			'populate_extras'   => true,
+			'update_meta_cache' => true,
+			'exclude'           => false,
+			'show_hidden'       => false,
 		);
 
 		$r = wp_parse_args( $args, $defaults );
@@ -441,7 +770,7 @@ class BP_Groups_Group {
 		}
 
 		// Get paginated results
-		$paged_groups_sql = apply_filters( 'bp_groups_get_paged_groups_sql', join( ' ', (array) $sql ), $sql );
+		$paged_groups_sql = apply_filters( 'bp_groups_get_paged_groups_sql', join( ' ', (array) $sql ), $sql, $r );
 		$paged_groups     = $wpdb->get_results( $paged_groups_sql );
 
 		$total_sql['select'] = "SELECT COUNT(DISTINCT g.id) FROM {$bp->groups->table_name} g, {$bp->groups->table_name_members} gm1, {$bp->groups->table_name_groupmeta} gm2";
@@ -494,7 +823,7 @@ class BP_Groups_Group {
 		}
 
 		// Get total group results
-		$total_groups_sql = apply_filters( 'bp_groups_get_total_groups_sql', $t_sql, $total_sql );
+		$total_groups_sql = apply_filters( 'bp_groups_get_total_groups_sql', $t_sql, $total_sql, $r );
 		$total_groups     = $wpdb->get_var( $total_groups_sql );
 
 		$group_ids = array();
@@ -504,12 +833,13 @@ class BP_Groups_Group {
 
 		// Populate some extra information instead of querying each time in the loop
 		if ( !empty( $r['populate_extras'] ) ) {
-			$group_ids = implode( ',', wp_parse_id_list( $group_ids ) );
 			$paged_groups = BP_Groups_Group::get_group_extras( $paged_groups, $group_ids, $r['type'] );
 		}
 
 		// Grab all groupmeta
-		bp_groups_update_meta_cache( $group_ids );
+		if ( ! empty( $r['update_meta_cache'] ) ) {
+			bp_groups_update_meta_cache( $group_ids );
+		}
 
 		unset( $sql, $total_sql );
 
@@ -525,12 +855,12 @@ class BP_Groups_Group {
 	 * WP_Query, we have to alter the return value (stripping the leading
 	 * AND keyword from the 'where' clause).
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 * @access protected
 	 *
 	 * @param array $meta_query An array of meta_query filters. See the
-	 *   documentation for WP_Meta_Query for details.
-	 * @return array $sql_array 'join' and 'where' clauses
+	 *        documentation for {@link WP_Meta_Query} for details.
+	 * @return array $sql_array 'join' and 'where' clauses.
 	 */
 	protected static function get_meta_query_sql( $meta_query = array() ) {
 		global $wpdb;
@@ -577,14 +907,18 @@ class BP_Groups_Group {
 	}
 
 	/**
-	 * Convert the 'type' parameter to 'order' and 'orderby'
+	 * Convert the 'type' parameter to 'order' and 'orderby'.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 * @access protected
-	 * @param string $type The 'type' shorthand param
-	 * @return array 'order' and 'orderby'
+	 *
+	 * @param string $type The 'type' shorthand param.
+	 * @return array {
+	 *	@type string $order SQL-friendly order string.
+	 *	@type string $orderby SQL-friendly orderby column name.
+	 * }
 	 */
-	protected function convert_type_to_order_orderby( $type = '' ) {
+	protected static function convert_type_to_order_orderby( $type = '' ) {
 		$order = $orderby = '';
 
 		switch ( $type ) {
@@ -618,14 +952,15 @@ class BP_Groups_Group {
 	}
 
 	/**
-	 * Convert the 'orderby' param into a proper SQL term/column
+	 * Convert the 'orderby' param into a proper SQL term/column.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 * @access protected
-	 * @param string $orderby
-	 * @return string $order_by_term
+	 *
+	 * @param string $orderby Orderby term as passed to get().
+	 * @return string $order_by_term SQL-friendly orderby term.
 	 */
-	protected function convert_orderby_to_order_by_term( $orderby ) {
+	protected static function convert_orderby_to_order_by_term( $orderby ) {
 		$order_by_term = '';
 
 		switch ( $orderby ) {
@@ -654,7 +989,29 @@ class BP_Groups_Group {
 		return $order_by_term;
 	}
 
-	function get_by_most_forum_topics( $limit = null, $page = null, $user_id = 0, $search_terms = false, $populate_extras = true, $exclude = false ) {
+	/**
+	 * Get a list of groups, sorted by those that have the most legacy forum topics.
+	 *
+	 * @param int $limit Optional. The max number of results to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page offset of results to return.
+	 *        Default: null (no limit).
+	 * @param int $user_id Optional. If present, groups will be limited to
+	 *        those of which the specified user is a member.
+	 * @param string $search_terms Optional. Limit groups to those whose
+	 *        name or description field contain the search string.
+	 * @param bool $populate_extras Optional. Whether to fetch extra
+	 *        information about the groups. Default: true.
+	 * @param string|array Optional. Array or comma-separated list of group
+	 *        IDs to exclude from results.
+	 * @return array {
+	 *     @type array $groups Array of group objects returned by the
+	 *           paginated query.
+	 *     @type int $total Total count of all groups matching non-
+	 *           paginated query params.
+	 * }
+	 */
+	public static function get_by_most_forum_topics( $limit = null, $page = null, $user_id = 0, $search_terms = false, $populate_extras = true, $exclude = false ) {
 		global $wpdb, $bp, $bbdb;
 
 		if ( empty( $bbdb ) )
@@ -687,15 +1044,38 @@ class BP_Groups_Group {
 		}
 
 		if ( !empty( $populate_extras ) ) {
-			foreach ( (array) $paged_groups as $group ) $group_ids[] = $group->id;
-			$group_ids = implode( ',', wp_parse_id_list( $group_ids ) );
+			foreach ( (array) $paged_groups as $group ) {
+				$group_ids[] = $group->id;
+			}
 			$paged_groups = BP_Groups_Group::get_group_extras( $paged_groups, $group_ids, 'newest' );
 		}
 
 		return array( 'groups' => $paged_groups, 'total' => $total_groups );
 	}
 
-	function get_by_most_forum_posts( $limit = null, $page = null, $search_terms = false, $populate_extras = true, $exclude = false ) {
+	/**
+	 * Get a list of groups, sorted by those that have the most legacy forum posts.
+	 *
+	 * @param int $limit Optional. The max number of results to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page offset of results to return.
+	 *        Default: null (no limit).
+	 * @param int $user_id Optional. If present, groups will be limited to
+	 *        those of which the specified user is a member.
+	 * @param string $search_terms Optional. Limit groups to those whose
+	 *        name or description field contain the search string.
+	 * @param bool $populate_extras Optional. Whether to fetch extra
+	 *        information about the groups. Default: true.
+	 * @param string|array Optional. Array or comma-separated list of group
+	 *        IDs to exclude from results.
+	 * @return array {
+	 *     @type array $groups Array of group objects returned by the
+	 *           paginated query.
+	 *     @type int $total Total count of all groups matching non-
+	 *           paginated query params.
+	 * }
+	 */
+	public static function get_by_most_forum_posts( $limit = null, $page = null, $search_terms = false, $populate_extras = true, $exclude = false ) {
 		global $wpdb, $bp, $bbdb;
 
 		if ( empty( $bbdb ) )
@@ -728,17 +1108,39 @@ class BP_Groups_Group {
 		}
 
 		if ( !empty( $populate_extras ) ) {
-			foreach ( (array) $paged_groups as $group ) $group_ids[] = $group->id;
-			$group_ids = implode( ',', wp_parse_id_list( $group_ids ) );
+			foreach ( (array) $paged_groups as $group ) {
+				$group_ids[] = $group->id;
+			}
 			$paged_groups = BP_Groups_Group::get_group_extras( $paged_groups, $group_ids, 'newest' );
 		}
 
 		return array( 'groups' => $paged_groups, 'total' => $total_groups );
 	}
 
-	function get_by_letter( $letter, $limit = null, $page = null, $populate_extras = true, $exclude = false ) {
+	/**
+	 * Get a list of groups whose names start with a given letter.
+	 *
+	 * @param string $letter The letter.
+	 * @param int $limit Optional. The max number of results to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page offset of results to return.
+	 *        Default: null (no limit).
+	 * @param bool $populate_extras Optional. Whether to fetch extra
+	 *        information about the groups. Default: true.
+	 * @param string|array Optional. Array or comma-separated list of group
+	 *        IDs to exclude from results.
+	 * @return array {
+	 *     @type array $groups Array of group objects returned by the
+	 *           paginated query.
+	 *     @type int $total Total count of all groups matching non-
+	 *           paginated query params.
+	 * }
+	 */
+	public static function get_by_letter( $letter, $limit = null, $page = null, $populate_extras = true, $exclude = false ) {
 		global $wpdb, $bp;
 
+		$pag_sql = $hidden_sql = $exclude_sql = '';
+
 		// Multibyte compliance
 		if ( function_exists( 'mb_strlen' ) ) {
 			if ( mb_strlen( $letter, 'UTF-8' ) > 1 || is_numeric( $letter ) || !$letter ) {
@@ -762,23 +1164,47 @@ class BP_Groups_Group {
 
 		if ( !empty( $limit ) && !empty( $page ) ) {
 			$pag_sql      = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
-			$total_groups = $wpdb->get_var( "SELECT COUNT(DISTINCT g.id) FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2, {$bp->groups->table_name} g WHERE g.id = gm1.group_id AND g.id = gm2.group_id AND gm2.meta_key = 'last_activity' AND gm1.meta_key = 'total_member_count' AND g.name LIKE '{$letter}%%' {$hidden_sql} {$exclude_sql}" );
 		}
 
+		$total_groups = $wpdb->get_var( "SELECT COUNT(DISTINCT g.id) FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2, {$bp->groups->table_name} g WHERE g.id = gm1.group_id AND g.id = gm2.group_id AND gm2.meta_key = 'last_activity' AND gm1.meta_key = 'total_member_count' AND g.name LIKE '{$letter}%%' {$hidden_sql} {$exclude_sql}" );
+
 		$paged_groups = $wpdb->get_results( "SELECT g.*, gm1.meta_value as total_member_count, gm2.meta_value as last_activity FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2, {$bp->groups->table_name} g WHERE g.id = gm1.group_id AND g.id = gm2.group_id AND gm2.meta_key = 'last_activity' AND gm1.meta_key = 'total_member_count' AND g.name LIKE '{$letter}%%' {$hidden_sql} {$exclude_sql} ORDER BY g.name ASC {$pag_sql}" );
 
 		if ( !empty( $populate_extras ) ) {
 			foreach ( (array) $paged_groups as $group ) {
 				$group_ids[] = $group->id;
 			}
-			$group_ids    = implode( ',', wp_parse_id_list( $group_ids ) );
 			$paged_groups = BP_Groups_Group::get_group_extras( $paged_groups, $group_ids, 'newest' );
 		}
 
 		return array( 'groups' => $paged_groups, 'total' => $total_groups );
 	}
 
-	function get_random( $limit = null, $page = null, $user_id = 0, $search_terms = false, $populate_extras = true, $exclude = false ) {
+	/**
+	 * Get a list of random groups.
+	 *
+	 * Use BP_Groups_Group::get() with 'type' = 'random' instead.
+	 *
+	 * @param int $limit Optional. The max number of results to return.
+	 *        Default: null (no limit).
+	 * @param int $page Optional. The page offset of results to return.
+	 *        Default: null (no limit).
+	 * @param int $user_id Optional. If present, groups will be limited to
+	 *        those of which the specified user is a member.
+	 * @param string $search_terms Optional. Limit groups to those whose
+	 *        name or description field contain the search string.
+	 * @param bool $populate_extras Optional. Whether to fetch extra
+	 *        information about the groups. Default: true.
+	 * @param string|array Optional. Array or comma-separated list of group
+	 *        IDs to exclude from results.
+	 * @return array {
+	 *     @type array $groups Array of group objects returned by the
+	 *           paginated query.
+	 *     @type int $total Total count of all groups matching non-
+	 *           paginated query params.
+	 * }
+	 */
+	public static function get_random( $limit = null, $page = null, $user_id = 0, $search_terms = false, $populate_extras = true, $exclude = false ) {
 		global $wpdb, $bp;
 
 		$pag_sql = $hidden_sql = $search_sql = $exclude_sql = '';
@@ -810,15 +1236,33 @@ class BP_Groups_Group {
 		}
 
 		if ( !empty( $populate_extras ) ) {
-			foreach ( (array) $paged_groups as $group ) $group_ids[] = $group->id;
-			$group_ids = implode( ',', wp_parse_id_list( $group_ids ) );
+			foreach ( (array) $paged_groups as $group ) {
+				$group_ids[] = $group->id;
+			}
 			$paged_groups = BP_Groups_Group::get_group_extras( $paged_groups, $group_ids, 'newest' );
 		}
 
 		return array( 'groups' => $paged_groups, 'total' => $total_groups );
 	}
 
-	function get_group_extras( &$paged_groups, &$group_ids, $type = false ) {
+	/**
+	 * Fetch extra data for a list of groups.
+	 *
+	 * This method is used throughout the class, by methods that take a
+	 * $populate_extras parameter.
+	 *
+	 * Data fetched:
+	 *
+	 *     - Logged-in user's status within each group (is_member,
+	 *       is_confirmed, is_pending, is_banned)
+	 *
+	 * @param array $paged_groups Array of groups.
+	 * @param string|array Array or comma-separated list of IDs matching
+	 *        $paged_groups.
+	 * @param string $type Not used.
+	 * @return array $paged_groups
+	 */
+	public static function get_group_extras( &$paged_groups, &$group_ids, $type = false ) {
 		global $bp, $wpdb;
 
 		if ( empty( $group_ids ) )
@@ -827,19 +1271,50 @@ class BP_Groups_Group {
 		// Sanitize group IDs
 		$group_ids = implode( ',', wp_parse_id_list( $group_ids ) );
 
-		// Fetch the logged in users status within each group
-		$user_status = $wpdb->get_col( $wpdb->prepare( "SELECT group_id FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id IN ( {$group_ids} ) AND is_confirmed = 1 AND is_banned = 0", bp_loggedin_user_id() ) );
+		// Fetch the logged-in user's status within each group
+		if ( is_user_logged_in() ) {
+			$user_status_results = $wpdb->get_results( $wpdb->prepare( "SELECT group_id, is_confirmed, invite_sent FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id IN ( {$group_ids} ) AND is_banned = 0", bp_loggedin_user_id() ) );
+		} else {
+			$user_status_results = array();
+		}
+
+		// Reindex
+		$user_status = array();
+		foreach ( $user_status_results as $user_status_result ) {
+			$user_status[ $user_status_result->group_id ] = $user_status_result;
+		}
+
 		for ( $i = 0, $count = count( $paged_groups ); $i < $count; ++$i ) {
-			$paged_groups[$i]->is_member = false;
+			$is_member = $is_invited = $is_pending = '0';
+			$gid = $paged_groups[ $i ]->id;
 
-			foreach ( (array) $user_status as $group_id ) {
-				if ( $group_id == $paged_groups[$i]->id ) {
-					$paged_groups[$i]->is_member = true;
+			if ( isset( $user_status[ $gid ] ) ) {
+
+				// is_confirmed means the user is a member
+				if ( $user_status[ $gid ]->is_confirmed ) {
+					$is_member = '1';
+
+				// invite_sent means the user has been invited
+				} else if ( $user_status[ $gid ]->invite_sent ) {
+					$is_invited = '1';
+
+				// User has sent request, but has not been confirmed
+				} else {
+					$is_pending = '1';
 				}
 			}
+
+			$paged_groups[ $i ]->is_member = $is_member;
+			$paged_groups[ $i ]->is_invited = $is_invited;
+			$paged_groups[ $i ]->is_pending = $is_pending;
+		}
+
+		if ( is_user_logged_in() ) {
+			$user_banned = $wpdb->get_col( $wpdb->prepare( "SELECT group_id FROM {$bp->groups->table_name_members} WHERE is_banned = 1 AND user_id = %d AND group_id IN ( {$group_ids} )", bp_loggedin_user_id() ) );
+		} else {
+			$user_banned = array();
 		}
 
-		$user_banned = $wpdb->get_col( $wpdb->prepare( "SELECT group_id FROM {$bp->groups->table_name_members} WHERE is_banned = 1 AND user_id = %d AND group_id IN ( {$group_ids} )", bp_loggedin_user_id() ) );
 		for ( $i = 0, $count = count( $paged_groups ); $i < $count; ++$i ) {
 			$paged_groups[$i]->is_banned = false;
 
@@ -853,13 +1328,29 @@ class BP_Groups_Group {
 		return $paged_groups;
 	}
 
-	function delete_all_invites( $group_id ) {
+	/**
+	 * Delete all invitations to a given group.
+	 *
+	 * @param int $group_id ID of the group whose invitations are being
+	 *        deleted.
+	 * @return int|null Number of rows records deleted on success, null on
+	 *         failure.
+	 */
+	public static function delete_all_invites( $group_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE group_id = %d AND invite_sent = 1", $group_id ) );
 	}
 
-	function get_total_group_count() {
+	/**
+	 * Get a total group count for the site.
+	 *
+	 * Will include hidden groups in the count only if
+	 * current_user_can( 'bp_moderate' ).
+	 *
+	 * @return int Group count.
+	 */
+	public static function get_total_group_count() {
 		global $wpdb, $bp;
 
 		$hidden_sql = '';
@@ -869,7 +1360,14 @@ class BP_Groups_Group {
 		return $wpdb->get_var( "SELECT COUNT(id) FROM {$bp->groups->table_name} {$hidden_sql}" );
 	}
 
-	function get_global_forum_topic_count( $type ) {
+	/**
+	 * Get global count of forum topics in public groups (legacy forums).
+	 *
+	 * @param $type Optional. If 'unreplied', count will be limited to
+	 *        those topics that have received no replies.
+	 * @return int Forum topic count.
+	 */
+	public static function get_global_forum_topic_count( $type ) {
 		global $bbdb, $wpdb, $bp;
 
 		if ( 'unreplied' == $type )
@@ -885,7 +1383,13 @@ class BP_Groups_Group {
 		return $wpdb->get_var( "SELECT COUNT(t.topic_id) FROM {$bbdb->topics} AS t, {$bp->groups->table_name} AS g LEFT JOIN {$bp->groups->table_name_groupmeta} AS gm ON g.id = gm.group_id WHERE (gm.meta_key = 'forum_id' AND gm.meta_value = t.forum_id) AND g.status = 'public' AND t.topic_status = '0' AND t.topic_sticky != '2' {$extra_sql} " );
 	}
 
-	function get_total_member_count( $group_id ) {
+	/**
+	 * Get the member count for a group.
+	 *
+	 * @param int $group_id Group ID.
+	 * @return int Count of confirmed members for the group.
+	 */
+	public static function get_total_member_count( $group_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 1 AND is_banned = 0", $group_id ) );
@@ -894,13 +1398,13 @@ class BP_Groups_Group {
 	/**
 	 * Get a total count of all topics of a given status, across groups/forums
 	 *
-	 * @package BuddyPress
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @param string $status 'public', 'private', 'hidden', 'all' Which group types to count
+	 * @param string $status Which group type to count. 'public', 'private',
+	 *        'hidden', or 'all'. Default: 'public'.
 	 * @return int The topic count
 	 */
-	function get_global_topic_count( $status = 'public', $search_terms = false ) {
+	public static function get_global_topic_count( $status = 'public', $search_terms = false ) {
 		global $bbdb, $wpdb, $bp;
 
 		switch ( $status ) {
@@ -937,16 +1441,16 @@ class BP_Groups_Group {
 	}
 
 	/**
-	 * Get an array containing ids for each group type
+	 * Get an array containing ids for each group type.
 	 *
 	 * A bit of a kludge workaround for some issues
-	 * with bp_has_groups()
+	 * with bp_has_groups().
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 *
 	 * @return array
 	 */
-	function get_group_type_ids() {
+	public static function get_group_type_ids() {
 		global $wpdb, $bp;
 
 		$ids = array();
@@ -961,30 +1465,54 @@ class BP_Groups_Group {
 }
 
 /**
- * Query for the members of a group
+ * Query for the members of a group.
+ *
+ * Special notes about the group members data schema:
+ * - *Members* are entries with is_confirmed = 1
+ * - *Pending requests* are entries with is_confirmed = 0 and inviter_id = 0
+ * - *Pending and sent invitations* are entries with is_confirmed = 0 and
+ *   inviter_id != 0 and invite_sent = 1
+ * - *Pending and unsent invitations* are entries with is_confirmed = 0 and
+ *   inviter_id != 0 and invite_sent = 0
+ * - *Membership requests* are entries with is_confirmed = 0 and
+ *   inviter_id = 0 (and invite_sent = 0)
  *
- * @since BuddyPress (1.8)
+ * @since BuddyPress (1.8.0)
+ *
+ * @param array $args {
+ *     Array of arguments. Accepts all arguments from
+ *     {@link BP_User_Query}, with the following additions:
+ *     @type int $group_id ID of the group to limit results to.
+ *     @type array $group_role Array of group roles to match ('member',
+ *           'mod', 'admin', 'banned'). Default: array( 'member' ).
+ *     @type bool $is_confirmed Whether to limit to confirmed members.
+ *           Default: true.
+ *     @type string $type Sort order. Accepts any value supported by
+ *           {@link BP_User_Query}, in addition to 'last_joined' and
+ *           'first_joined'. Default: 'last_joined'.
+ * }
  */
 class BP_Group_Member_Query extends BP_User_Query {
+
 	/**
-	 * Array of group member ids, cached to prevent redundant lookups
+	 * Array of group member ids, cached to prevent redundant lookups.
 	 *
-	 * @var null|array Null if not yet defined, otherwise an array of ints
 	 * @since BuddyPress (1.8.1)
+	 * @var null|array Null if not yet defined, otherwise an array of ints.
 	 */
 	protected $group_member_ids;
 
 	/**
-	 * Set up action hooks
+	 * Set up action hooks.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public function setup_hooks() {
 		// Take this early opportunity to set the default 'type' param
-		// to 'last_modified', which will ensure that BP_User_Query
+		// to 'last_joined', which will ensure that BP_User_Query
 		// trusts our order and does not try to apply its own
 		if ( empty( $this->query_vars_raw['type'] ) ) {
-			$this->query_vars_raw['type'] = 'last_modified';
+			$this->query_vars_raw['type'] = 'last_joined';
 		}
 
 		// Set the sort order
@@ -995,16 +1523,18 @@ class BP_Group_Member_Query extends BP_User_Query {
 	}
 
 	/**
-	 * Get a list of user_ids to include in the IN clause of the main query
+	 * Get a list of user_ids to include in the IN clause of the main query.
 	 *
 	 * Overrides BP_User_Query::get_include_ids(), adding our additional
 	 * group-member logic.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param array
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param array $include Existing group IDs in the $include parameter,
+	 *        as calculated in BP_User_Query.
 	 * @return array
 	 */
-	public function get_include_ids( $include ) {
+	public function get_include_ids( $include = array() ) {
 		// The following args are specific to group member queries, and
 		// are not present in the query_vars of a normal BP_User_Query.
 		// We loop through to make sure that defaults are set (though
@@ -1014,6 +1544,9 @@ class BP_Group_Member_Query extends BP_User_Query {
 			'group_id'     => 0,
 			'group_role'   => array( 'member' ),
 			'is_confirmed' => true,
+			'invite_sent'  => null,
+			'inviter_id'   => null,
+			'type'         => 'last_joined',
 		) );
 
 		$group_member_ids = $this->get_group_member_ids();
@@ -1032,10 +1565,11 @@ class BP_Group_Member_Query extends BP_User_Query {
 	}
 
 	/**
-	 * Get the members of the queried group
+	 * Get the members of the queried group.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @return array $ids User IDs of relevant group member ids
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @return array $ids User IDs of relevant group member ids.
 	 */
 	protected function get_group_member_ids() {
 		global $wpdb;
@@ -1050,7 +1584,6 @@ class BP_Group_Member_Query extends BP_User_Query {
 			'where'   => array(),
 			'orderby' => '',
 			'order'   => '',
-			'limit'   => '',
 		);
 
 		/** WHERE clauses *****************************************************/
@@ -1062,6 +1595,35 @@ class BP_Group_Member_Query extends BP_User_Query {
 		$is_confirmed = ! empty( $this->query_vars['is_confirmed'] ) ? 1 : 0;
 		$sql['where'][] = $wpdb->prepare( "is_confirmed = %d", $is_confirmed );
 
+		// invite_sent
+		if ( ! is_null( $this->query_vars['invite_sent'] ) ) {
+			$invite_sent = ! empty( $this->query_vars['invite_sent'] ) ? 1 : 0;
+			$sql['where'][] = $wpdb->prepare( "invite_sent = %d", $invite_sent );
+		}
+
+		// inviter_id
+		if ( ! is_null( $this->query_vars['inviter_id'] ) ) {
+			$inviter_id = $this->query_vars['inviter_id'];
+
+			// Empty: inviter_id = 0. (pass false, 0, or empty array)
+			if ( empty( $inviter_id ) ) {
+				$sql['where'][] = "inviter_id = 0";
+
+			// The string 'any' matches any non-zero value (inviter_id != 0)
+			} else if ( 'any' === $inviter_id ) {
+				$sql['where'][] = "inviter_id != 0";
+
+			// Assume that a list of inviter IDs has been passed
+			} else {
+				// Parse and sanitize
+				$inviter_ids = wp_parse_id_list( $inviter_id );
+				if ( ! empty( $inviter_ids ) ) {
+					$inviter_ids_sql = implode( ',', $inviter_ids );
+					$sql['where'][] = "inviter_id IN ({$inviter_ids_sql})";
+				}
+			}
+		}
+
 		// Role information is stored as follows: admins have
 		// is_admin = 1, mods have is_mod = 1, banned have is_banned =
 		// 1, and members have all three set to 0.
@@ -1113,27 +1675,31 @@ class BP_Group_Member_Query extends BP_User_Query {
 
 		$sql['where'] = ! empty( $sql['where'] ) ? 'WHERE ' . implode( ' AND ', $sql['where'] ) : '';
 
-		/** ORDER BY clause ***************************************************/
-
-		// @todo For now, mimicking legacy behavior of
-		// bp_group_has_members(), which has us order by date_modified
-		// only. Should abstract it in the future
+		// We fetch group members in order of last_joined, regardless
+		// of 'type'. If the 'type' value is not 'last_joined' or
+		// 'first_joined', the order will be overridden in
+		// BP_Group_Member_Query::set_orderby()
 		$sql['orderby'] = "ORDER BY date_modified";
-		$sql['order']   = "DESC";
+		$sql['order']   = 'first_joined' === $this->query_vars['type'] ? 'ASC' : 'DESC';
+
+		$this->group_member_ids = $wpdb->get_col( "{$sql['select']} {$sql['where']} {$sql['orderby']} {$sql['order']}" );
 
-		/** LIMIT clause ******************************************************/
-		$this->group_member_ids = $wpdb->get_col( "{$sql['select']} {$sql['where']} {$sql['orderby']} {$sql['order']} {$sql['limit']}" );
+		/**
+		 * Use this filter to build a custom query (such as when you've
+		 * defined a custom 'type').
+		 */
+		$this->group_member_ids = apply_filters( 'bp_group_member_query_group_member_ids', $this->group_member_ids, $this );
 
 		return $this->group_member_ids;
 	}
 
 	/**
-	 * Tell BP_User_Query to order by the order of our query results
+	 * Tell BP_User_Query to order by the order of our query results.
 	 *
-	 * This implementation assumes the 'last_modified' sort order
-	 * hardcoded in BP_Group_Member_Query::get_group_member_ids().
+	 * We only override BP_User_Query's native ordering in case of the
+	 * 'last_joined' and 'first_joined' $type parameters.
 	 *
-	 * @param object $query BP_User_Query object
+	 * @param BP_User_Query $query BP_User_Query object.
 	 */
 	public function set_orderby( $query ) {
 		$gm_ids = $this->get_group_member_ids();
@@ -1141,11 +1707,18 @@ class BP_Group_Member_Query extends BP_User_Query {
 			$gm_ids = array( 0 );
 		}
 
-		// The first param in the FIELD() clause is the sort column id
-		$gm_ids = array_merge( array( 'u.id' ), wp_parse_id_list( $gm_ids ) );
-		$gm_ids_sql = implode( ',', $gm_ids );
+		// For 'last_joined' and 'first_joined' types, we force
+		// the order according to the query performed in
+		// BP_Group_Member_Query::get_group_members(). Otherwise, fall
+		// through and let BP_User_Query do its own ordering.
+		if ( in_array( $query->query_vars['type'], array( 'last_joined', 'first_joined' ) ) ) {
 
-		$query->uid_clauses['orderby'] = "ORDER BY FIELD(" . $gm_ids_sql . ")";
+			// The first param in the FIELD() clause is the sort column id
+			$gm_ids = array_merge( array( 'u.id' ), wp_parse_id_list( $gm_ids ) );
+			$gm_ids_sql = implode( ',', $gm_ids );
+
+			$query->uid_clauses['orderby'] = "ORDER BY FIELD(" . $gm_ids_sql . ")";
+		}
 
 		// Prevent this filter from running on future BP_User_Query
 		// instances on the same page
@@ -1153,9 +1726,15 @@ class BP_Group_Member_Query extends BP_User_Query {
 	}
 
 	/**
-	 * Fetch additional data required in bp_group_has_members() loops
+	 * Fetch additional data required in bp_group_has_members() loops.
+	 *
+	 * Additional data fetched:
+	 *
+	 *      - is_banned
+	 *      - date_modified
+	 *
+	 * @since BuddyPress (1.8.0)
 	 *
-	 * @since BuddyPress (1.8)
 	 * @param object $query BP_User_Query object. Because we're filtering
 	 *   the current object, we use $this inside of the method instead
 	 * @param string $user_ids_sql Sanitized, comma-separated string of
@@ -1165,14 +1744,22 @@ class BP_Group_Member_Query extends BP_User_Query {
 		global $wpdb;
 
 		$bp     = buddypress();
-		$extras = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, date_modified, is_banned FROM {$bp->groups->table_name_members} WHERE user_id IN ({$user_ids_sql}) AND group_id = %d", $this->query_vars['group_id'] ) );
+		$extras = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, date_modified, is_admin, is_mod, comments, user_title, invite_sent, is_confirmed, inviter_id, is_banned FROM {$bp->groups->table_name_members} WHERE user_id IN ({$user_ids_sql}) AND group_id = %d", $this->query_vars['group_id'] ) );
 
 		foreach ( (array) $extras as $extra ) {
 			if ( isset( $this->results[ $extra->user_id ] ) ) {
 				// user_id is provided for backward compatibility
 				$this->results[ $extra->user_id ]->user_id       = (int) $extra->user_id;
+				$this->results[ $extra->user_id ]->is_admin      = (int) $extra->is_admin;
+				$this->results[ $extra->user_id ]->is_mod        = (int) $extra->is_mod;
 				$this->results[ $extra->user_id ]->is_banned     = (int) $extra->is_banned;
 				$this->results[ $extra->user_id ]->date_modified = $extra->date_modified;
+				$this->results[ $extra->user_id ]->user_title    = $extra->user_title;
+				$this->results[ $extra->user_id ]->comments      = $extra->comments;
+				$this->results[ $extra->user_id ]->invite_sent   = (int) $extra->invite_sent;
+				$this->results[ $extra->user_id ]->inviter_id    = (int) $extra->inviter_id;
+				$this->results[ $extra->user_id ]->is_confirmed  = (int) $extra->is_confirmed;
+				$this->results[ $extra->user_id ]->membership_id = (int) $extra->id;
 			}
 		}
 
@@ -1181,22 +1768,139 @@ class BP_Group_Member_Query extends BP_User_Query {
 	}
 }
 
+/**
+ * BuddyPress Group Membership objects.
+ */
 class BP_Groups_Member {
+
+	/**
+	 * ID of the membership.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $id;
+
+	/**
+	 * ID of the group associated with the membership.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $group_id;
+
+	/**
+	 * ID of the user associated with the membership.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $user_id;
+
+	/**
+	 * ID of the user whose invitation initiated the membership.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $inviter_id;
+
+	/**
+	 * Whether the member is an admin of the group.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $is_admin;
+
+	/**
+	 * Whether the member is a mod of the group.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $is_mod;
+
+	/**
+	 * Whether the member is banned from the group.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $is_banned;
+
+	/**
+	 * Title used to describe the group member's role in the group.
+	 *
+	 * Eg, 'Group Admin'.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $user_title;
+
+	/**
+	 * Last modified date of the membership.
+	 *
+	 * This value is updated when, eg, invitations are accepted.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $date_modified;
+
+	/**
+	 * Whether the membership has been confirmed.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $is_confirmed;
+
+	/**
+	 * Comments associated with the membership.
+	 *
+	 * In BP core, these are limited to the optional message users can
+	 * include when requesting membership to a private group.
+	 *
+	 * @access public
+	 * @var string
+	 */
 	var $comments;
+
+	/**
+	 * Whether an invitation has been sent for this membership.
+	 *
+	 * The purpose of this flag is to mark when an invitation has been
+	 * "drafted" (the user has been added via the interface at Send
+	 * Invites), but the Send button has not been pressed, so the
+	 * invitee has not yet been notified.
+	 *
+	 * @access public
+	 * @var int
+	 */
 	var $invite_sent;
+
+	/**
+	 * WP_User object representing the membership's user.
+	 *
+	 * @access public
+	 * @var WP_User
+	 */
 	var $user;
 
-	function __construct( $user_id = 0, $group_id = 0, $id = false, $populate = true ) {
+	/**
+	 * Constructor method.
+	 *
+	 * @param int $user_id Optional. Along with $group_id, can be used to
+	 *        look up a membership.
+	 * @param int $group_id Optional. Along with $user_id, can be used to
+	 *        look up a membership.
+	 * @param int $id Optional. The unique ID of the membership object.
+	 * @param bool $populate Whether to populate the properties of the
+	 *        located membership. Default: true.
+	 */
+	public function __construct( $user_id = 0, $group_id = 0, $id = false, $populate = true ) {
 
 		// User and group are not empty, and ID is
 		if ( !empty( $user_id ) && !empty( $group_id ) && empty( $id ) ) {
@@ -1218,7 +1922,10 @@ class BP_Groups_Member {
 		}
 	}
 
-	function populate() {
+	/**
+	 * Populate the object's properties.
+	 */
+	public function populate() {
 		global $wpdb, $bp;
 
 		if ( $this->user_id && $this->group_id && !$this->id )
@@ -1247,7 +1954,12 @@ class BP_Groups_Member {
 		}
 	}
 
-	function save() {
+	/**
+	 * Save the membership data to the database.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function save() {
 		global $wpdb, $bp;
 
 		$this->user_id       = apply_filters( 'groups_member_user_id_before_save',       $this->user_id,       $this->id );
@@ -1291,7 +2003,13 @@ class BP_Groups_Member {
 		return true;
 	}
 
-	function promote( $status = 'mod' ) {
+	/**
+	 * Promote a member to a new status.
+	 *
+	 * @param string $status The new status. 'mod' or 'admin'.
+	 * @return bool True on success, false on failure.
+	 */
+	public function promote( $status = 'mod' ) {
 		if ( 'mod' == $status ) {
 			$this->is_admin   = 0;
 			$this->is_mod     = 1;
@@ -1307,7 +2025,12 @@ class BP_Groups_Member {
 		return $this->save();
 	}
 
-	function demote() {
+	/**
+	 * Demote membership to Member status (non-admin, non-mod).
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function demote() {
 		$this->is_mod     = 0;
 		$this->is_admin   = 0;
 		$this->user_title = false;
@@ -1315,7 +2038,12 @@ class BP_Groups_Member {
 		return $this->save();
 	}
 
-	function ban() {
+	/**
+	 * Ban the user from the group.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function ban() {
 		if ( !empty( $this->is_admin ) )
 			return false;
 
@@ -1325,7 +2053,12 @@ class BP_Groups_Member {
 		return $this->save();
 	}
 
-	function unban() {
+	/**
+	 * Unban the user from the group.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function unban() {
 		if ( !empty( $this->is_admin ) )
 			return false;
 
@@ -1334,18 +2067,29 @@ class BP_Groups_Member {
 		return $this->save();
 	}
 
-	function accept_invite() {
+	/**
+	 * Mark a pending invitation as accepted.
+	 */
+	public function accept_invite() {
 		$this->inviter_id    = 0;
 		$this->is_confirmed  = 1;
 		$this->date_modified = bp_core_current_time();
 	}
 
-	function accept_request() {
+	/**
+	 * Confirm a membership request.
+	 */
+	public function accept_request() {
 		$this->is_confirmed = 1;
 		$this->date_modified = bp_core_current_time();
 	}
 
-	function remove() {
+	/**
+	 * Remove the current membership.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function remove() {
 		global $wpdb, $bp;
 
 		$sql = $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d", $this->user_id, $this->group_id );
@@ -1362,31 +2106,40 @@ class BP_Groups_Member {
 		return $result;
 	}
 
-	/** Static Methods ********************************************************/
+	/** Static Methods ****************************************************/
 
 	/**
-	 * Refresh the total_group_count for a user
+	 * Refresh the total_group_count for a user.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param int $user_id
-	 * @return bool True on success
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param int $user_id ID of the user.
+	 * @return bool True on success, false on failure.
 	 */
 	public static function refresh_total_group_count_for_user( $user_id ) {
 		return bp_update_user_meta( $user_id, 'total_group_count', (int) self::total_group_count( $user_id ) );
 	}
 
 	/**
-	 * Refresh the total_member_count for a group
+	 * Refresh the total_member_count for a group.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param int $group_id
-	 * @return bool True on success
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return bool True on success, false on failure.
 	 */
 	public static function refresh_total_member_count_for_group( $group_id ) {
 		return groups_update_groupmeta( $group_id, 'total_member_count', (int) BP_Groups_Group::get_total_member_count( $group_id ) );
 	}
 
-	function delete( $user_id, $group_id ) {
+	/**
+	 * Delete a membership, based on user + group IDs.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @return True on success, false on failure.
+	 */
+	public static function delete( $user_id, $group_id ) {
 		global $wpdb, $bp;
 
 		$remove = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d", $user_id, $group_id ) );
@@ -1400,7 +2153,20 @@ class BP_Groups_Member {
 		return $remove;
 	}
 
-	function get_group_ids( $user_id, $limit = false, $page = false ) {
+	/**
+	 * Get the IDs of the groups of which a specified user is a member.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $limit Optional. Max number of results to return.
+	 *        Default: false (no limit).
+	 * @param int $page Optional. Page offset of results to return.
+	 *        Default: false (no limit).
+	 * @return array {
+	 *     @type array $groups Array of groups returned by paginated query.
+	 *     @type int $total Count of groups matching query.
+	 * }
+	 */
+	public static function get_group_ids( $user_id, $limit = false, $page = false ) {
 		global $wpdb, $bp;
 
 		$pag_sql = '';
@@ -1421,7 +2187,22 @@ class BP_Groups_Member {
 		return array( 'groups' => $groups, 'total' => (int) $total_groups );
 	}
 
-	function get_recently_joined( $user_id, $limit = false, $page = false, $filter = false ) {
+	/**
+	 * Get the IDs of the groups of which a specified user is a member, sorted by the date joined.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $limit Optional. Max number of results to return.
+	 *        Default: false (no limit).
+	 * @param int $page Optional. Page offset of results to return.
+	 *        Default: false (no limit).
+	 * @param string $filter Optional. Limit results to groups whose name or
+	 *        description field matches search terms.
+	 * @return array {
+	 *     @type array $groups Array of groups returned by paginated query.
+	 *     @type int $total Count of groups matching query.
+	 * }
+	 */
+	public static function get_recently_joined( $user_id, $limit = false, $page = false, $filter = false ) {
 		global $wpdb, $bp;
 
 		$pag_sql = $hidden_sql = $filter_sql = '';
@@ -1443,7 +2224,22 @@ class BP_Groups_Member {
 		return array( 'groups' => $paged_groups, 'total' => $total_groups );
 	}
 
-	function get_is_admin_of( $user_id, $limit = false, $page = false, $filter = false ) {
+	/**
+	 * Get the IDs of the groups of which a specified user is an admin.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $limit Optional. Max number of results to return.
+	 *        Default: false (no limit).
+	 * @param int $page Optional. Page offset of results to return.
+	 *        Default: false (no limit).
+	 * @param string $filter Optional. Limit results to groups whose name or
+	 *        description field matches search terms.
+	 * @return array {
+	 *     @type array $groups Array of groups returned by paginated query.
+	 *     @type int $total Count of groups matching query.
+	 * }
+	 */
+	public static function get_is_admin_of( $user_id, $limit = false, $page = false, $filter = false ) {
 		global $wpdb, $bp;
 
 		$pag_sql = $hidden_sql = $filter_sql = '';
@@ -1465,7 +2261,22 @@ class BP_Groups_Member {
 		return array( 'groups' => $paged_groups, 'total' => $total_groups );
 	}
 
-	function get_is_mod_of( $user_id, $limit = false, $page = false, $filter = false ) {
+	/**
+	 * Get the IDs of the groups of which a specified user is a moderator.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $limit Optional. Max number of results to return.
+	 *        Default: false (no limit).
+	 * @param int $page Optional. Page offset of results to return.
+	 *        Default: false (no limit).
+	 * @param string $filter Optional. Limit results to groups whose name or
+	 *        description field matches search terms.
+	 * @return array {
+	 *     @type array $groups Array of groups returned by paginated query.
+	 *     @type int $total Count of groups matching query.
+	 * }
+	 */
+	public static function get_is_mod_of( $user_id, $limit = false, $page = false, $filter = false ) {
 		global $wpdb, $bp;
 
 		$pag_sql = $hidden_sql = $filter_sql = '';
@@ -1487,7 +2298,13 @@ class BP_Groups_Member {
 		return array( 'groups' => $paged_groups, 'total' => $total_groups );
 	}
 
-	function total_group_count( $user_id = 0 ) {
+	/**
+	 * Get the count of groups of which the specified user is a member.
+	 *
+	 * @param int $user_id Optional. Default: ID of the displayed user.
+	 * @return int Group count.
+	 */
+	public static function total_group_count( $user_id = 0 ) {
 		global $bp, $wpdb;
 
 		if ( empty( $user_id ) )
@@ -1500,7 +2317,22 @@ class BP_Groups_Member {
 		}
 	}
 
-	function get_invites( $user_id, $limit = false, $page = false, $exclude = false ) {
+	/**
+	 * Get a user's outstanding group invitations.
+	 *
+	 * @param int $user_id ID of the invitee.
+	 * @param int $limit Optional. Max number of results to return.
+	 *        Default: false (no limit).
+	 * @param int $page Optional. Page offset of results to return.
+	 *        Default: false (no limit).
+	 * @param string|array $exclude Optional. Array or comma-separated list
+	 *        of group IDs to exclude from results.
+	 * @return array {
+	 *     @type array $groups Array of groups returned by paginated query.
+	 *     @type int $total Count of groups matching query.
+	 * }
+	 */
+	public static function get_invites( $user_id, $limit = false, $page = false, $exclude = false ) {
 		global $wpdb, $bp;
 
 		$pag_sql = ( !empty( $limit ) && !empty( $page ) ) ? $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) ) : '';
@@ -1513,12 +2345,44 @@ class BP_Groups_Member {
 		}
 
 		$paged_groups = $wpdb->get_results( $wpdb->prepare( "SELECT g.*, gm1.meta_value as total_member_count, gm2.meta_value as last_activity FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2, {$bp->groups->table_name_members} m, {$bp->groups->table_name} g WHERE g.id = m.group_id AND g.id = gm1.group_id AND g.id = gm2.group_id AND gm2.meta_key = 'last_activity' AND gm1.meta_key = 'total_member_count' AND m.is_confirmed = 0 AND m.inviter_id != 0 AND m.invite_sent = 1 AND m.user_id = %d {$exclude_sql} ORDER BY m.date_modified ASC {$pag_sql}", $user_id ) );
-		$total_groups = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT m.group_id) FROM {$bp->groups->table_name_members} m, {$bp->groups->table_name} g WHERE m.group_id = g.id AND m.is_confirmed = 0 AND m.inviter_id != 0 AND m.invite_sent = 1 AND m.user_id = %d {$exclude_sql} ORDER BY date_modified ASC", $user_id ) );
 
-		return array( 'groups' => $paged_groups, 'total' => $total_groups );
+		return array( 'groups' => $paged_groups, 'total' => self::get_invite_count_for_user( $user_id ) );
 	}
 
-	function check_has_invite( $user_id, $group_id, $type = 'sent' ) {
+	/**
+	 * Gets the total group invite count for a user.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param int $user_id The user ID
+	 * @return int
+	 */
+	public static function get_invite_count_for_user( $user_id = 0 ) {
+		global $wpdb;
+
+		$bp = buddypress();
+
+		$count = wp_cache_get( $user_id, 'bp_group_invite_count' );
+
+		if ( false === $count ) {
+			$count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT m.group_id) FROM {$bp->groups->table_name_members} m, {$bp->groups->table_name} g WHERE m.group_id = g.id AND m.is_confirmed = 0 AND m.inviter_id != 0 AND m.invite_sent = 1 AND m.user_id = %d", $user_id ) );
+			wp_cache_set( $user_id, $count, 'bp_group_invite_count' );
+		}
+
+		return $count;
+	}
+
+	/**
+	 * Check whether a user has an outstanding invitation to a given group.
+	 *
+	 * @param int $user_id ID of the potential invitee.
+	 * @param int $group_id ID of the group.
+	 * @param string $type If 'sent', results are limited to those
+	 *        invitations that have actually been sent (non-draft).
+	 *        Default: 'sent'.
+	 * @return int|null The ID of the invitation if found, otherwise null.
+	 */
+	public static function check_has_invite( $user_id, $group_id, $type = 'sent' ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -1532,7 +2396,14 @@ class BP_Groups_Member {
 		return $wpdb->get_var( $wpdb->prepare( $sql, $user_id, $group_id ) );
 	}
 
-	function delete_invite( $user_id, $group_id ) {
+	/**
+	 * Delete an invitation, by specifying user ID and group ID.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @return int Number of records deleted.
+	 */
+	public static function delete_invite( $user_id, $group_id ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -1541,7 +2412,14 @@ class BP_Groups_Member {
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_confirmed = 0 AND inviter_id != 0 AND invite_sent = 1", $user_id, $group_id ) );
 	}
 
-	function delete_request( $user_id, $group_id ) {
+	/**
+	 * Delete an unconfirmed membership request, by user ID and group ID.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @return int Number of records deleted.
+	 */
+	public static function delete_request( $user_id, $group_id ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -1550,7 +2428,15 @@ class BP_Groups_Member {
  		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_confirmed = 0 AND inviter_id = 0 AND invite_sent = 0", $user_id, $group_id ) );
 	}
 
-	function check_is_admin( $user_id, $group_id ) {
+	/**
+	 * Check whether a user is an admin of a given group.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @param int|null ID of the membership if the user is an admin,
+	 *        otherwise null.
+	 */
+	public static function check_is_admin( $user_id, $group_id ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -1559,7 +2445,15 @@ class BP_Groups_Member {
 		return $wpdb->query( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_admin = 1 AND is_banned = 0", $user_id, $group_id ) );
 	}
 
-	function check_is_mod( $user_id, $group_id ) {
+	/**
+	 * Check whether a user is a mod of a given group.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @param int|null ID of the membership if the user is a mod,
+	 *        otherwise null.
+	 */
+	public static function check_is_mod( $user_id, $group_id ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -1568,7 +2462,15 @@ class BP_Groups_Member {
 		return $wpdb->query( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_mod = 1 AND is_banned = 0", $user_id, $group_id ) );
 	}
 
-	function check_is_member( $user_id, $group_id ) {
+	/**
+	 * Check whether a user is a member of a given group.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @param int|null ID of the membership if the user is a member,
+	 *        otherwise null.
+	 */
+	public static function check_is_member( $user_id, $group_id ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -1577,7 +2479,15 @@ class BP_Groups_Member {
 		return $wpdb->query( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_confirmed = 1 AND is_banned = 0", $user_id, $group_id ) );
 	}
 
-	function check_is_banned( $user_id, $group_id ) {
+	/**
+	 * Check whether a user is banned from a given group.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @param int|null ID of the membership if the user is banned,
+	 *        otherwise null.
+	 */
+	public static function check_is_banned( $user_id, $group_id ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -1589,13 +2499,14 @@ class BP_Groups_Member {
 	/**
 	 * Is the specified user the creator of the group?
 	 *
-	 * @global object $bp BuddyPress global settings
-	 * @global wpdb $wpdb WordPress database object
-	 * @param int $user_id
-	 * @param int $group_id
 	 * @since BuddyPress (1.2.6)
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @return int|null ID of the group if the user is the creator,
+	 *         otherwise false.
 	 */
-	function check_is_creator( $user_id, $group_id ) {
+	public static function check_is_creator( $user_id, $group_id ) {
 		global $bp, $wpdb;
 
 		if ( empty( $user_id ) )
@@ -1604,7 +2515,14 @@ class BP_Groups_Member {
 		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name} WHERE creator_id = %d AND id = %d", $user_id, $group_id ) );
 	}
 
-	function check_for_membership_request( $user_id, $group_id ) {
+	/**
+	 * Check whether a user has an outstanding membership request for a given group.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $group_id ID of the group.
+	 * @return int|null ID of the membership if found, otherwise false.
+	 */
+	public static function check_for_membership_request( $user_id, $group_id ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
@@ -1613,7 +2531,14 @@ class BP_Groups_Member {
 		return $wpdb->query( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_confirmed = 0 AND is_banned = 0 AND inviter_id = 0", $user_id, $group_id ) );
 	}
 
-	function get_random_groups( $user_id = 0, $total_groups = 5 ) {
+	/**
+	 * Get a list of randomly selected IDs of groups that the member belongs to.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @param int $total_groups Max number of group IDs to return. Default: 5.
+	 * @return array Group IDs.
+	 */
+	public static function get_random_groups( $user_id = 0, $total_groups = 5 ) {
 		global $wpdb, $bp;
 
 		// If the user is logged in and viewing their random groups, we can show hidden and private groups
@@ -1624,31 +2549,60 @@ class BP_Groups_Member {
 		}
 	}
 
-	function get_group_member_ids( $group_id ) {
+	/**
+	 * Get the IDs of all a given group's members.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return array IDs of all group members.
+	 */
+	public static function get_group_member_ids( $group_id ) {
 		global $bp, $wpdb;
 
 		return $wpdb->get_col( $wpdb->prepare( "SELECT user_id FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 1 AND is_banned = 0", $group_id ) );
 	}
 
-	function get_group_administrator_ids( $group_id ) {
+	/**
+	 * Get a list of all a given group's admins.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return array Info about group admins (user_id + date_modified).
+	 */
+	public static function get_group_administrator_ids( $group_id ) {
 		global $bp, $wpdb;
 
 		return $wpdb->get_results( $wpdb->prepare( "SELECT user_id, date_modified FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_admin = 1 AND is_banned = 0", $group_id ) );
 	}
 
-	function get_group_moderator_ids( $group_id ) {
+	/**
+	 * Get a list of all a given group's moderators.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return array Info about group mods (user_id + date_modified).
+	 */
+	public static function get_group_moderator_ids( $group_id ) {
 		global $bp, $wpdb;
 
 		return $wpdb->get_results( $wpdb->prepare( "SELECT user_id, date_modified FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_mod = 1 AND is_banned = 0", $group_id ) );
 	}
 
-	function get_all_membership_request_user_ids( $group_id ) {
+	/**
+	 * Get the IDs users with outstanding membership requests to the group.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return array IDs of users with outstanding membership requests.
+	 */
+	public static function get_all_membership_request_user_ids( $group_id ) {
 		global $bp, $wpdb;
 
 		return $wpdb->get_col( $wpdb->prepare( "SELECT user_id FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 0 AND inviter_id = 0", $group_id ) );
 	}
 
-	function get_all_for_group( $group_id, $limit = false, $page = false, $exclude_admins_mods = true, $exclude_banned = true, $exclude = false ) {
+	/**
+	 * Get members of a group.
+	 *
+	 * @deprecated BuddyPress (1.8.0)
+	 */
+	public static function get_all_for_group( $group_id, $limit = false, $page = false, $exclude_admins_mods = true, $exclude_banned = true, $exclude = false ) {
 		global $bp, $wpdb;
 
 		_deprecated_function( __METHOD__, '1.8', 'BP_Group_Member_Query' );
@@ -1707,22 +2661,26 @@ class BP_Groups_Member {
 		return array( 'members' => $members, 'count' => $total_member_count );
 	}
 
-	function delete_all( $group_id ) {
+	/**
+	 * Delete all memberships for a given group.
+	 *
+	 * @param int $group_id ID of the group.
+	 * @return int Number of records deleted.
+	 */
+	public static function delete_all( $group_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE group_id = %d", $group_id ) );
 	}
 
 	/**
-	 * Delete all group membership information for the specified user
+	 * Delete all group membership information for the specified user.
+	 *
+	 * @since BuddyPress (1.0.0)
 	 *
-	 * @global object $bp BuddyPress global settings
-	 * @global wpdb $wpdb WordPress database object
-	 * @param int $user_id
-	 * @since BuddyPress (1.0)
-	 * @uses BP_Groups_Member
+	 * @param int $user_id ID of the user.
 	 */
-	function delete_all_for_user( $user_id ) {
+	public static function delete_all_for_user( $user_id ) {
 		global $bp, $wpdb;
 
 		// Get all the group ids for the current user's groups and update counts
@@ -1813,115 +2771,152 @@ class BP_Groups_Member {
  *
  * @package BuddyPress
  * @subpackage Groups
- * @since BuddyPress (1.1)
+ * @since BuddyPress (1.1.0)
  */
 class BP_Group_Extension {
 
-	/** Public ****************************************************************/
+	/** Public ************************************************************/
 
 	/**
-	 * @var array Information about this extension's screens
-	 * @since BuddyPress (1.8)
+	 * Information about this extension's screens.
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var array
 	 */
 	public $screens = array();
 
 	/**
-	 * @var string The name of the extending class
-	 * @since BuddyPress (1.8)
+	 * The name of the extending class.
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var string
 	 */
 	public $class_name = '';
 
 	/**
-	 * @var object A ReflectionClass object of the current extension
-	 * @since BuddyPress (1.8)
+	 * A ReflectionClass object of the current extension.
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var ReflectionClass
 	 */
 	public $class_reflection = null;
 
 	/**
-	 * @var array Parsed configuration paramaters for the extension
-	 * @since BuddyPress (1.8)
+	 * Parsed configuration paramaters for the extension.
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var array
 	 */
 	public $params = array();
 
 	/**
-	 * @var int The id of the current group
-	 * @since BuddyPress (1.8)
+	 * The ID of the current group.
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var int
 	 */
 	public $group_id = 0;
 
 	/**
-	 * @var string The slug of the current extension
+	 * The slug of the current extension.
+	 *
+	 * @var string
 	 */
 	public $slug = '';
 
 	/**
-	 * @var string The translatable name of the current extension
+	 * The translatable name of the current extension.
+	 *
+	 * @var string
 	 */
 	public $name = '';
 
 	/**
-	 * @var string Whether the extension tab is visible. 'public'
-	 *   or 'private'
+	 * The visibility of the extension tab. 'public' or 'private'.
+	 *
+	 * @var string
 	 */
 	public $visibility = 'public';
 
 	/**
-	 * @var int The numeric position of the main nav item
+	 * The numeric position of the main nav item.
+	 *
+	 * @var int
 	 */
 	public $nav_item_position = 81;
 
 	/**
-	 * @var bool Whether to show the nav item
+	 * Whether to show the nav item.
+	 *
+	 * @var bool
 	 */
 	public $enable_nav_item = true;
 
 	/**
-	 * @var string The text of the nav item. Defaults to self::name
+	 * The text of the nav item. Defaults to self::name.
+	 *
+	 * @var string
 	 */
 	public $nav_item_name = '';
 
 	/**
-	 * @var string The WP action that self::widget_display() is attached to.
-	 *   Defaults to 'groups_custom_group_boxes'
+	 * The WP action that self::widget_display() is attached to.
+	 *
+	 * Default: 'groups_custom_group_boxes'.
+	 *
+	 * @var string
 	 */
 	public $display_hook = 'groups_custom_group_boxes';
 
 	/**
-	 * @var string The template file used to load the plugin content.
-	 *   Defaults to 'groups/single/plugins'
+	 * The template file used to load the plugin content.
+	 *
+	 * Default: 'groups/single/plugins'.
+	 *
+	 * @var string
 	 */
 	public $template_file = 'groups/single/plugins';
 
-	/** Protected *************************************************************/
+	/** Protected *********************************************************/
 
 	/**
-	 * @var bool Has the extension been initialized?
-	 * @since BuddyPress (1.8)
+	 * Has the extension been initialized?
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var bool
 	 */
 	protected $initialized = false;
 
 	/**
-	 * @var array Extension properties as set by legacy extensions
-	 * @since BuddyPress (1.8)
+	 * Extension properties as set by legacy extensions.
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var array
 	 */
 	protected $legacy_properties = array();
 
 	/**
-	 * @var array Extension properties as set by legacy extensions, but
-	 *   converted to match the new format for params
-	 * @since BuddyPress (1.8)
+	 * Converted legacy parameters.
+	 *
+	 * These are the extension properties as set by legacy extensions, but
+	 * then converted to match the new format for params.
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var array
 	 */
 	protected $legacy_properties_converted = array();
 
 	/**
-	 * @var array Miscellaneous data as set by the __set() magic method
-	 * @since BuddyPress (1.8)
+	 * Miscellaneous data as set by the __set() magic method.
+	 *
+	 * @since BuddyPress (1.8.0)
+	 * @var array
 	 */
 	protected $data = array();
 
-	/** Screen Overrides ******************************************************/
+	/** Screen Overrides **************************************************/
 
-	/**
+	/*
 	 * Screen override methods are how your extension will display content
 	 * and handle form submits. Your extension should only override those
 	 * methods that it needs for its purposes.
@@ -1966,7 +2961,33 @@ class BP_Group_Extension {
 	 *   }
 	 *
 	 * @since BuddyPress (1.8)
-	 * @param array $args See inline definition below for arguments
+	 * @param array $args {
+	 *     Array of initialization arguments.
+	 *     @type string $slug Unique, URL-safe identifier for your
+	 *           extension.
+	 *     @type string $name Translatable name for your extension. Used to
+	 *           populate navigation items.
+	 *     @type string $visibility Optional. Set to 'public' for your
+	 *           extension (the main tab as well as the widget) to be
+	 *           available to anyone who can access the group; set to
+	 *           'private' otherwise. Default: 'public'.
+	 *     @type int $nav_item_position Optional. Location of the nav item
+	 *           in the tab list. Default: 81.
+	 *     @type bool $enable_nav_item Optional. Whether the extension's
+	 *           tab should be accessible to anyone who can view the group.
+	 *           Default: true.
+	 *     @type string $nav_item_name Optional. The translatable text you
+	 *           want to appear in the nav tab. Default: the value of $name.
+	 *     @type string $display_hook Optional. The WordPress action that
+	 *           the widget_display() method is hooked to.
+	 *           Default: 'groups_custom_group_boxes'.
+	 *     @type string $template_file Optional. Theme-relative path to the
+	 *           template file BP should use to load the content of your
+	 *           main extension tab. Default: 'groups/single/plugins.php'.
+	 *     @type array $screens A multi-dimensional array of configuration
+	 *           information for the extension screens. See docblock of
+	 *           {@link BP_Group_Extension} for more details.
+	 * }
 	 */
 	public function init( $args = array() ) {
 
@@ -1995,7 +3016,7 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * The main setup routine for the extension
+	 * The main setup routine for the extension.
 	 *
 	 * This method contains the primary logic for setting up an extension's
 	 * configuration, setting up backward compatibility for legacy plugins,
@@ -2006,7 +3027,7 @@ class BP_Group_Extension {
 	 * is called automatically at the right point in the load order by
 	 * bp_register_group_extension().
 	 *
-	 * @since BuddyPress (1.1)
+	 * @since BuddyPress (1.1.0)
 	 */
 	public function _register() {
 
@@ -2044,13 +3065,13 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Set up some basic info about the Extension
+	 * Set up some basic info about the Extension.
 	 *
 	 * Here we collect the name of the extending class, as well as a
 	 * ReflectionClass that is used in get_screen_callback() to determine
 	 * whether your extension overrides certain callback methods.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	protected function setup_class_info() {
 		if ( empty( $this->class_name ) ) {
@@ -2063,14 +3084,14 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Get the current group id
+	 * Get the current group ID.
 	 *
 	 * Check for:
 	 *   - current group
 	 *   - new group
 	 *   - group admin
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public static function get_group_id() {
 
@@ -2099,9 +3120,9 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Gather configuration data about your screens
+	 * Gather configuration data about your screens.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	protected function get_default_screens() {
 		$this->setup_class_info();
@@ -2132,9 +3153,9 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Set up screens array based on params
+	 * Set up screens array based on params.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	protected function setup_screens() {
 		foreach ( (array) $this->params['screens'] as $context => $screen ) {
@@ -2150,12 +3171,12 @@ class BP_Group_Extension {
 		}
 	}
 
-	/** Display ***************************************************************/
+	/** Display ***********************************************************/
 
 	/**
-	 * Hook this extension's group tab into BuddyPress, if necessary
+	 * Hook this extension's group tab into BuddyPress, if necessary.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	protected function setup_display_hooks() {
 
@@ -2195,19 +3216,19 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Hooks the main display method, and loads the template file
+	 * Hook the main display method, and loads the template file
 	 */
 	public function _display_hook() {
 		add_action( 'bp_template_content', array( &$this, 'display' ) );
 		bp_core_load_template( apply_filters( 'bp_core_template_plugin', $this->template_file ) );
 	}
 
-	/** Create ****************************************************************/
+	/** Create ************************************************************/
 
 	/**
-	 * Hook this extension's Create step into BuddyPress, if necessary
+	 * Hook this extension's Create step into BuddyPress, if necessary.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	protected function setup_create_hooks() {
 		if ( ! $this->is_screen_enabled( 'create' ) ) {
@@ -2233,9 +3254,9 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Call the create_screen() method, if we're on the right page
+	 * Call the create_screen() method, if we're on the right page.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public function maybe_create_screen() {
 		if ( ! bp_is_group_creation_step( $this->screens['create']['slug'] ) ) {
@@ -2247,13 +3268,13 @@ class BP_Group_Extension {
 
 		// The create screen requires an additional nonce field
 		// due to a quirk in the way the templates are built
-		wp_nonce_field( 'groups_create_save_' . bp_get_groups_current_create_step() );
+		wp_nonce_field( 'groups_create_save_' . bp_get_groups_current_create_step(), '_wpnonce', false );
 	}
 
 	/**
-	 * Call the create_screen_save() method, if we're on the right page
+	 * Call the create_screen_save() method, if we're on the right page.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public function maybe_create_screen_save() {
 		if ( ! bp_is_group_creation_step( $this->screens['create']['slug'] ) ) {
@@ -2264,12 +3285,12 @@ class BP_Group_Extension {
 		call_user_func( $this->screens['create']['screen_save_callback'], $this->group_id );
 	}
 
-	/** Edit ******************************************************************/
+	/** Edit **************************************************************/
 
 	/**
-	 * Hook this extension's Edit panel into BuddyPress, if necessary
+	 * Hook this extension's Edit panel into BuddyPress, if necessary.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	protected function setup_edit_hooks() {
 
@@ -2314,7 +3335,7 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Call the edit_screen() method
+	 * Call the edit_screen() method.
 	 *
 	 * Previous versions of BP_Group_Extension required plugins to provide
 	 * their own Submit button and nonce fields when building markup. In
@@ -2326,7 +3347,7 @@ class BP_Group_Extension {
 	 * button, as would be present in legacy plugins; if one is found, we
 	 * do not auto-add our own button.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public function call_edit_screen() {
 		ob_start();
@@ -2340,9 +3361,9 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Check the nonce, and call the edit_screen_save() method
+	 * Check the nonce, and call the edit_screen_save() method.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public function call_edit_screen_save() {
 		if ( empty( $_POST ) ) {
@@ -2360,7 +3381,7 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Load the template that houses the Edit screen
+	 * Load the template that houses the Edit screen.
 	 *
 	 * Separated out into a callback so that it can run after all other
 	 * Group Extensions have had a chance to register their navigation, to
@@ -2368,16 +3389,17 @@ class BP_Group_Extension {
 	 *
 	 * Hooked to 'bp_screens'.
 	 *
-	 * @see BP_Group_Extension::setup_edit_hooks()
+	 * @since BuddyPress (1.8.0)
 	 * @access public So that do_action() has access. Do not call directly.
-	 * @since BuddyPress (1.8)
+	 *
+	 * @see BP_Group_Extension::setup_edit_hooks()
 	 */
 	public function call_edit_screen_template_loader() {
 		bp_core_load_template( $this->edit_screen_template );
 	}
 
 	/**
-	 * Add a submit button to the edit form, if it needs one
+	 * Add a submit button to the edit form, if it needs one.
 	 *
 	 * There's an inconsistency in the way that the group Edit and Create
 	 * screens are rendered: the Create screen has a submit button built
@@ -2386,9 +3408,11 @@ class BP_Group_Extension {
 	 * use on both the Create and Edit screens - BP will provide the button
 	 * if one is not found.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param string $screen The screen markup, captured in the output buffer
-	 * @param string $screen The same markup, with a submit button added
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param string $screen The screen markup, captured in the output
+	 *        buffer.
+	 * @param string $screen The same markup, with a submit button added.
 	 */
 	protected function maybe_add_submit_button( $screen = '' ) {
 		if ( $this->has_submit_button( $screen ) ) {
@@ -2406,9 +3430,10 @@ class BP_Group_Extension {
 	/**
 	 * Does the given markup have a submit button?
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param string $screen The markup to check
-	 * @return bool
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param string $screen The markup to check.
+	 * @return bool True if a Submit button is found, otherwise false.
 	 */
 	public static function has_submit_button( $screen = '' ) {
 		$pattern = "/<input[^>]+type=[\'\"]submit[\'\"]/";
@@ -2416,12 +3441,12 @@ class BP_Group_Extension {
 		return ! empty( $matches[0] );
 	}
 
-	/** Admin *****************************************************************/
+	/** Admin *************************************************************/
 
 	/**
-	 * Hook this extension's Admin metabox into BuddyPress, if necessary
+	 * Hook this extension's Admin metabox into BuddyPress, if necessary.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	protected function setup_admin_hooks() {
 		if ( ! $this->is_screen_enabled( 'admin' ) || ! is_admin() ) {
@@ -2439,9 +3464,9 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Call the admin_screen() method, and add a nonce field
+	 * Call the admin_screen() method, and add a nonce field.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public function call_admin_screen() {
 		call_user_func( $this->screens['admin']['screen_callback'], $this->group_id );
@@ -2451,7 +3476,7 @@ class BP_Group_Extension {
 	/**
 	 * Check the nonce, and call the admin_screen_save() method
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	public function call_admin_screen_save() {
 		$this->check_nonce( 'admin' );
@@ -2459,9 +3484,9 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Create the Dashboard meta box for this extension
+	 * Create the Dashboard meta box for this extension.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function _meta_box_display_callback() {
 		$group_id = isset( $_GET['gid'] ) ? (int) $_GET['gid'] : 0;
@@ -2478,10 +3503,10 @@ class BP_Group_Extension {
 	}
 
 
-	/** Utilities *************************************************************/
+	/** Utilities *********************************************************/
 
 	/**
-	 * Generate the nonce fields for a settings form
+	 * Generate the nonce fields for a settings form.
 	 *
 	 * The nonce field name (the second param passed to wp_nonce_field)
 	 * contains this extension's slug and is thus unique to this extension.
@@ -2489,20 +3514,24 @@ class BP_Group_Extension {
 	 * more than one extension may generate nonces on the same page, and we
 	 * must avoid name clashes.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
+	 *
 	 * @uses wp_nonce_field()
-	 * @param string $context 'create', 'edit', 'admin'
+	 *
+	 * @param string $context Screen context. 'create', 'edit', or 'admin'.
 	 */
 	public function nonce_field( $context = '' ) {
 		wp_nonce_field( 'bp_group_extension_' . $this->slug . '_' . $context, '_bp_group_' . $context . '_nonce_' . $this->slug );
 	}
 
 	/**
-	 * Check the nonce on a submitted settings form
+	 * Check the nonce on a submitted settings form.
+	 *
+	 * @since BuddyPress (1.8.0)
 	 *
-	 * @since BuddyPress (1.8)
 	 * @uses check_admin_referer()
-	 * @param string $context 'create', 'edit', 'admin'
+	 *
+	 * @param string $context Screen context. 'create', 'edit', or 'admin'.
 	 */
 	public function check_nonce( $context = '' ) {
 		check_admin_referer( 'bp_group_extension_' . $this->slug . '_' . $context, '_bp_group_' . $context . '_nonce_' . $this->slug );
@@ -2515,9 +3544,11 @@ class BP_Group_Extension {
 	 * (legacy: $this->enable_create_step, etc), and its screen_callback
 	 * must also exist and be callable.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param string $context 'create', 'edit', 'admin'
-	 * @return bool
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param string $context Screen context. 'create', 'edit', or 'admin'.
+	 *
+	 * @return bool True if the screen is enabled, otherwise false.
 	 */
 	public function is_screen_enabled( $context = '' ) {
 		$enabled = false;
@@ -2530,7 +3561,7 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Get the appropriate screen callback for the specified context/type
+	 * Get the appropriate screen callback for the specified context/type.
 	 *
 	 * BP Group Extensions have three special "screen contexts": create,
 	 * admin, and edit. Each of these contexts has a corresponding
@@ -2561,10 +3592,12 @@ class BP_Group_Extension {
 	 * The get_screen_callback() method uses a ReflectionClass object to
 	 * determine whether your extension has provided a given callback.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param string $context 'create', 'edit', 'admin'
-	 * @param string $type 'screen', 'screen_save'
-	 * @return mixed A callable function handle
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param string $context Screen context. 'create', 'edit', or 'admin'.
+	 * @param string $type Screen type. 'screen' or 'screen_save'. Default:
+	 *        'screen'.
+	 * @return callable A callable function handle.
 	 */
 	public function get_screen_callback( $context = '', $type = 'screen' ) {
 		$callback = '';
@@ -2588,7 +3621,7 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Recursive argument parsing
+	 * Recursive argument parsing.
 	 *
 	 * This acts like a multi-dimensional version of wp_parse_args() (minus
 	 * the querystring parsing - you must pass arrays).
@@ -2609,10 +3642,11 @@ class BP_Group_Extension {
 	 * in unexpected results when used with data in the wild. See, eg,
 	 * http://core.trac.wordpress.org/ticket/19888
 	 *
-	 * @since BuddyPress (1.8)
-	 * @arg array $a
-	 * @arg array $b
-	 * @return array
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param array $a First set of arguments.
+	 * @param array $b Second set of arguments.
+	 * @return array Parsed arguments.
 	 */
 	public static function parse_args_r( &$a, $b ) {
 		$a = (array) $a;
@@ -2632,7 +3666,7 @@ class BP_Group_Extension {
 
 	/** Legacy Support ********************************************************/
 
-	/**
+	/*
 	 * In BuddyPress 1.8, the recommended technique for configuring
 	 * extensions changed from directly setting various object properties
 	 * in the class constructor, to passing a configuration array to
@@ -2642,7 +3676,7 @@ class BP_Group_Extension {
 	 */
 
 	/**
-	 * Provide access to otherwise unavailable object properties
+	 * Provide access to otherwise unavailable object properties.
 	 *
 	 * This magic method is here for backward compatibility with plugins
 	 * that refer to config properties that have moved to a different
@@ -2652,9 +3686,10 @@ class BP_Group_Extension {
 	 * The legacy_properties array is set up in
 	 * self::setup_legacy_properties().
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param string $key
-	 * @return mixed
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param string $key Property name.
+	 * @return mixed The value if found, otherwise null.
 	 */
 	public function __get( $key ) {
 		if ( isset( $this->legacy_properties[ $key ] ) ) {
@@ -2667,17 +3702,18 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Provide a fallback for isset( $this->foo ) when foo is unavailable
+	 * Provide a fallback for isset( $this->foo ) when foo is unavailable.
 	 *
-	 * This magit method is here for backward compatibility with plugins
+	 * This magic method is here for backward compatibility with plugins
 	 * that have set their class config options directly in the class
 	 * constructor. The parse_legacy_properties() method of the current
 	 * class needs to check whether any legacy keys have been put into the
 	 * $this->data array.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param string $key
-	 * @return bool
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param string $key Property name.
+	 * @return bool True if the value is set, otherwise false.
 	 */
 	public function __isset( $key ) {
 		if ( isset( $this->legacy_properties[ $key ] ) ) {
@@ -2690,16 +3726,17 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Allow plugins to set otherwise unavailable object properties
+	 * Allow plugins to set otherwise unavailable object properties.
 	 *
 	 * This magic method is here for backward compatibility with plugins
 	 * that may attempt to modify the group extension by manually assigning
 	 * a value to an object property that no longer exists, such as
 	 * $this->enable_create_step.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @param string $key
-	 * @param mixed $value
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @param string $key Property name.
+	 * @param mixed $value Property value.
 	 */
 	public function __set( $key, $value ) {
 
@@ -2756,13 +3793,14 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Returns a list of legacy properties
+	 * Return a list of legacy properties.
 	 *
 	 * The legacy implementation of BP_Group_Extension used all of these
 	 * object properties for configuration. Some have been moved.
 	 *
-	 * @since BuddyPress (1.8)
-	 * @return array
+	 * @since BuddyPress (1.8.0)
+	 *
+	 * @return array List of legacy property keys.
 	 */
 	protected function get_legacy_property_list() {
 		return array(
@@ -2788,7 +3826,7 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Parse legacy properties
+	 * Parse legacy properties.
 	 *
 	 * The old standard for BP_Group_Extension was for plugins to register
 	 * their settings as properties in their constructor. The new method is
@@ -2796,7 +3834,7 @@ class BP_Group_Extension {
 	 * legacy plugins, we slurp up legacy properties, and later on we'll
 	 * parse them into the new init() array.
 	 *
-	 * @since BuddyPress (1.8)
+	 * @since BuddyPress (1.8.0)
 	 */
 	protected function parse_legacy_properties() {
 
@@ -2870,16 +3908,16 @@ class BP_Group_Extension {
 	}
 
 	/**
-	 * Set up legacy properties
+	 * Set up legacy properties.
 	 *
 	 * This method is responsible for ensuring that all legacy config
 	 * properties are stored in an array $this->legacy_properties, so that
 	 * they remain available to plugins that reference the variables at
 	 * their old locations.
 	 *
-	 * @see self::__get()
+	 * @since BuddyPress (1.8.0)
 	 *
-	 * @since BuddyPress (1.8)
+	 * @see BP_Group_Extension::__get()
 	 */
 	protected function setup_legacy_properties() {
 
@@ -2948,6 +3986,12 @@ class BP_Group_Extension {
 	}
 }
 
+/**
+ * Register a new Group Extension.
+ *
+ * @param string Name of the Extension class.
+ * @return bool|null Returns false on failure, otherwise null.
+ */
 function bp_register_group_extension( $group_extension_class = '' ) {
 
 	if ( ! class_exists( $group_extension_class ) ) {
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-filters.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-filters.php
index 08b9040b8fa92ea90857ec08913979f333ebac85..593f3e95b638601e77a2b9d59052e3db8b724c2f 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-filters.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-filters.php
@@ -51,6 +51,16 @@ add_filter( 'groups_new_group_forum_desc', 'bp_create_excerpt' );
 add_filter( 'groups_group_name_before_save',        'force_balance_tags' );
 add_filter( 'groups_group_description_before_save', 'force_balance_tags' );
 
+// Trim trailing spaces from name and description when saving
+add_filter( 'groups_group_name_before_save',        'trim' );
+add_filter( 'groups_group_description_before_save', 'trim' );
+
+// Escape output of new group creation details
+add_filter( 'bp_get_new_group_id',          'esc_attr'     );
+add_filter( 'bp_get_new_group_name',        'esc_attr'     );
+add_filter( 'bp_get_new_group_description', 'esc_textarea' );
+
+// Format numberical output
 add_filter( 'bp_get_total_group_count',      'bp_core_number_format' );
 add_filter( 'bp_get_group_total_for_member', 'bp_core_number_format' );
 add_filter( 'bp_get_group_total_members',    'bp_core_number_format' );
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-forums.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-forums.php
index d87018811f106ff5f244e2603ef29f3a5f102932..600fff3730025e359e183009ce718ac351ef88da 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-forums.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-forums.php
@@ -7,6 +7,9 @@
  * have a template screen associated with them. Usually they will send the user
  * back to the default screen after execution.
  *
+ * Note that this file is only used for the retired version of bbPress (1.x) and
+ * will see minimal updates as of BuddyPress 1.9.0.
+ *
  * @package BuddyPress
  * @subpackage GroupsForums
  */
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-functions.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-functions.php
index 3f1d4eb66bcfbab359f5eac114ca57e8488d79c5..cfa573257121e8586b6285db52dbf0e872bd52e2 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-functions.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-functions.php
@@ -40,77 +40,103 @@ function bp_groups_has_directory() {
  * @return BP_Groups_Group $group The group object
  */
 function groups_get_group( $args = '' ) {
-	$defaults = array(
-		'group_id'   => false,
-		'load_users' => false
-	);
-
-	$args = wp_parse_args( $args, $defaults );
-	extract( $args, EXTR_SKIP );
+	$r = wp_parse_args( $args, array(
+		'group_id'          => false,
+		'load_users'        => false,
+		'populate_extras'   => false,
+	) );
 
-	$cache_key = 'bp_groups_group_' . $group_id . ( $load_users ? '_load_users' : '_noload_users' );
+	$group_args = array(
+		'populate_extras' => $r['populate_extras'],
+	);
 
-	if ( !$group = wp_cache_get( $cache_key, 'bp' ) ) {
-		$group = new BP_Groups_Group( $group_id, true, $load_users );
-		wp_cache_set( $cache_key, $group, 'bp' );
-	}
+	$group = new BP_Groups_Group( $r['group_id'], $group_args );
 
 	return apply_filters( 'groups_get_group', $group );
 }
 
 /*** Group Creation, Editing & Deletion *****************************************/
 
+/**
+ * Create a group.
+ *
+ * @since BuddyPress (1.0.0)
+ *
+ * @param array $args {
+ *     An array of arguments.
+ *     @type int|bool $group_id Pass a group ID to update an existing item, or
+ *           0 / false to create a new group. Default: 0.
+ *     @type int $creator_id The user ID that creates the group.
+ *     @type string $name The group name.
+ *     @type string $description Optional. The group's description.
+ *     @type string $slug The group slug.
+ *     @type string $status The group's status. Accepts 'public', 'private' or
+             'hidden'. Defaults to 'public'.
+ *     @type int $enable_forum Optional. Whether the group has a forum enabled.
+ *           If the legacy forums are enabled for this group or if a bbPress
+ *           forum is enabled for the group, set this to 1. Default: 0.
+ *     @type string $date_created The GMT time, in Y-m-d h:i:s format,
+ *           when the group was created. Defaults to the current time.
+ * }
+ * @return int|bool The ID of the group on success. False on error.
+ */
 function groups_create_group( $args = '' ) {
 
-	extract( $args );
-
-	/**
-	 * Possible parameters (pass as assoc array):
-	 *	'group_id'
-	 *	'creator_id'
-	 *	'name'
-	 *	'description'
-	 *	'slug'
-	 *	'status'
-	 *	'enable_forum'
-	 *	'date_created'
-	 */
-
-	if ( !empty( $group_id ) )
-		$group = groups_get_group( array( 'group_id' => $group_id ) );
-	else
-		$group = new BP_Groups_Group;
+	$defaults = array(
+		'group_id'     => 0,
+		'creator_id'   => 0,
+		'name'         => '',
+		'description'  => '',
+		'slug'         => '',
+		'status'       => 'public',
+		'enable_forum' => 0,
+		'date_created' => bp_core_current_time()
+	);
 
-	if ( !empty( $creator_id ) )
-		$group->creator_id = $creator_id;
-	else
-		$group->creator_id = bp_loggedin_user_id();
+	$args = wp_parse_args( $args, $defaults );
+	extract( $args, EXTR_SKIP );
 
-	if ( isset( $name ) )
-		$group->name = $name;
+	// Pass an existing group ID
+	if ( ! empty( $group_id ) ) {
+		$group = groups_get_group( array( 'group_id' => (int) $group_id ) );
+		$name  = ! empty( $name ) ? $name : $group->name;
+		$slug  = ! empty( $slug ) ? $slug : $group->slug;
 
-	if ( isset( $description ) )
-		$group->description = $description;
+		// Groups need at least a name
+		if ( empty( $name ) ) {
+			return false;
+		}
 
-	if ( isset( $slug ) && groups_check_slug( $slug ) )
-		$group->slug = $slug;
+	// Create a new group
+	} else {
+		// Instantiate new group object
+		$group = new BP_Groups_Group;
+	}
 
-	if ( isset( $status ) ) {
-		if ( groups_is_valid_status( $status ) ) {
-			$group->status = $status;
-		}
+	// Set creator ID
+	if ( ! empty( $creator_id ) ) {
+		$group->creator_id = (int) $creator_id;
+	} else {
+		$group->creator_id = bp_loggedin_user_id();
 	}
 
-	if ( isset( $enable_forum ) )
-		$group->enable_forum = $enable_forum;
-	else if ( empty( $group_id ) && !isset( $enable_forum ) )
-		$group->enable_forum = 1;
+	// Validate status
+	if ( ! groups_is_valid_status( $status ) ) {
+		return false;
+	}
 
-	if ( isset( $date_created ) )
-		$group->date_created = $date_created;
+	// Set group name
+	$group->name         = $name;
+	$group->description  = $description;
+	$group->slug         = $slug;
+	$group->status       = $status;
+	$group->enable_forum = (int) $enable_forum;
+	$group->date_created = $date_created;
 
-	if ( !$group->save() )
+	// Save group
+	if ( ! $group->save() ) {
 		return false;
+	}
 
 	// If this is a new group, set up the creator as the first member and admin
 	if ( empty( $group_id ) ) {
@@ -200,30 +226,21 @@ function groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_
  * @since BuddyPress (1.0)
  */
 function groups_delete_group( $group_id ) {
-	global $bp;
-
-	// Check the user is the group admin.
-	if ( ! bp_is_item_admin() )
-		return false;
 
 	do_action( 'groups_before_delete_group', $group_id );
 
 	// Get the group object
 	$group = groups_get_group( array( 'group_id' => $group_id ) );
-	if ( !$group->delete() )
-		return false;
 
-	// Delete all group activity from activity streams
-	if ( bp_is_active( 'activity' ) )
-		bp_activity_delete_by_item_id( array( 'item_id' => $group_id, 'component' => $bp->groups->id ) );
+	// Bail if group cannot be deleted
+	if ( ! $group->delete() ) {
+		return false;
+	}
 
 	// Remove all outstanding invites for this group
 	groups_delete_all_group_invites( $group_id );
 
-	// Remove all notifications for any user belonging to this group
-	bp_core_delete_all_notifications_by_type( $group_id, $bp->groups->id );
-
-	do_action( 'groups_delete_group', $group_id);
+	do_action( 'groups_delete_group', $group_id );
 
 	return true;
 }
@@ -292,19 +309,10 @@ function groups_leave_group( $group_id, $user_id = 0 ) {
 		}
 	}
 
-	$membership = new BP_Groups_Member( $user_id, $group_id );
-
 	// This is exactly the same as deleting an invite, just is_confirmed = 1 NOT 0.
-	if ( !groups_uninvite_user( $user_id, $group_id ) )
+	if ( !groups_uninvite_user( $user_id, $group_id ) ) {
 		return false;
-
-	/**
-	 * If the user joined this group less than five minutes ago, remove the
-	 * joined_group activity so users cannot flood the activity stream by
-	 * joining/leaving the group in quick succession.
-	 */
-	if ( bp_is_active( 'activity' ) && gmmktime() <= strtotime( '+5 minutes', (int)strtotime( $membership->date_modified ) ) )
-		bp_activity_delete( array( 'component' => $bp->groups->id, 'type' => 'joined_group', 'user_id' => $user_id, 'item_id' => $group_id ) );
+	}
 
 	bp_core_add_message( __( 'You successfully left the group.', 'buddypress' ) );
 
@@ -350,10 +358,9 @@ function groups_join_group( $group_id, $user_id = 0 ) {
 
 	// Record this in activity streams
 	groups_record_activity( array(
-		'action'  => apply_filters( 'groups_activity_joined_group', sprintf( __( '%1$s joined the group %2$s', 'buddypress'), bp_core_get_userlink( $user_id ), '<a href="' . bp_get_group_permalink( $group ) . '">' . esc_attr( bp_get_group_name( $group ) ) . '</a>' ) ),
 		'type'    => 'joined_group',
 		'item_id' => $group_id,
-		'user_id' => $user_id
+		'user_id' => $user_id,
 	) );
 
 	// Modify group meta
@@ -375,7 +382,7 @@ function groups_get_group_mods( $group_id ) {
 }
 
 /**
- * Fetch the members of a group
+ * Fetch the members of a group.
  *
  * Since BuddyPress 1.8, a procedural wrapper for BP_Group_Member_Query.
  * Previously called BP_Groups_Member::get_all_for_group().
@@ -383,47 +390,91 @@ function groups_get_group_mods( $group_id ) {
  * To use the legacy query, filter 'bp_use_legacy_group_member_query',
  * returning true.
  *
- * @param int $group_id
- * @param int $limit Maximum members to return
- * @param int $page The page of results to return (requires $limit)
- * @param bool $exclude_admins_mods Whether to exclude admins and mods
- * @param bool $exclude_banned Whether to exclude banned users
- * @param array|string $exclude Array or comma-sep list of users to exclude
- * @return array Multi-d array of 'members' list and 'count'
+ * @param array $args {
+ *     An array of optional arguments.
+ *     @type int $group_id ID of the group whose members are being queried.
+ *           Default: current group ID.
+ *     @type int $page Page of results to be queried. Default: 1.
+ *     @type int $per_page Number of items to return per page of results.
+ *           Default: 20.
+ *     @type int $max Optional. Max number of items to return.
+ *     @type array $exclude Optional. Array of user IDs to exclude.
+ *     @type bool|int True (or 1) to exclude admins and mods from results.
+ *           Default: 1.
+ *     @type bool|int True (or 1) to exclude banned users from results.
+ *           Default: 1.
+ *     @type array $group_role Optional. Array of group roles to include.
+ *     @type string $search_terms Optional. Filter results by a search string.
+ *     @type string $type Optional. Sort the order of results. 'last_joined',
+ *           'first_joined', or any of the $type params available in
+ *           {@link BP_User_Query}. Default: 'last_joined'.
+ * }
+ * @return array Multi-d array of 'members' list and 'count'.
  */
-function groups_get_group_members( $group_id, $limit = false, $page = false, $exclude_admins_mods = true, $exclude_banned = true, $exclude = false, $group_role = false ) {
+function groups_get_group_members( $args = array() ) {
+
+	// Backward compatibility with old method of passing arguments
+	if ( ! is_array( $args ) || func_num_args() > 1 ) {
+		_deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
+
+		$old_args_keys = array(
+			0 => 'group_id',
+			1 => 'per_page',
+			2 => 'page',
+			3 => 'exclude_admins_mods',
+			4 => 'exclude_banned',
+			5 => 'exclude',
+			6 => 'group_role',
+		);
+
+		$func_args = func_get_args();
+		$args      = bp_core_parse_args_array( $old_args_keys, $func_args );
+	}
+
+	$r = wp_parse_args( $args, array(
+		'group_id'            => bp_get_current_group_id(),
+		'per_page'            => false,
+		'page'                => false,
+		'exclude_admins_mods' => true,
+		'exclude_banned'      => true,
+		'exclude'             => false,
+		'group_role'          => array(),
+		'search_terms'        => false,
+		'type'                => 'last_joined',
+	) );
 
 	// For legacy users. Use of BP_Groups_Member::get_all_for_group()
 	// is deprecated. func_get_args() can't be passed to a function in PHP
 	// 5.2.x, so we create a variable
 	$func_args = func_get_args();
 	if ( apply_filters( 'bp_use_legacy_group_member_query', false, __FUNCTION__, $func_args ) ) {
-		$retval = BP_Groups_Member::get_all_for_group( $group_id, $limit, $page, $exclude_admins_mods, $exclude_banned, $exclude );
+		$retval = BP_Groups_Member::get_all_for_group( $r['group_id'], $r['per_page'], $r['page'], $r['exclude_admins_mods'], $r['exclude_banned'], $r['exclude'] );
 	} else {
 
 		// exclude_admins_mods and exclude_banned are legacy arguments.
 		// Convert to group_role
-		if ( empty( $group_role ) ) {
-			$group_role = array( 'member' );
+		if ( empty( $r['group_role'] ) ) {
+			$r['group_role'] = array( 'member' );
 
-			if ( ! $exclude_admins_mods ) {
-				$group_role[] = 'mod';
-				$group_role[] = 'admin';
+			if ( ! $r['exclude_admins_mods'] ) {
+				$r['group_role'][] = 'mod';
+				$r['group_role'][] = 'admin';
 			}
 
-			if ( ! $exclude_banned ) {
-				$group_role[] = 'banned';
+			if ( ! $r['exclude_banned'] ) {
+				$r['group_role'][] = 'banned';
 			}
 		}
 
 		// Perform the group member query (extends BP_User_Query)
 		$members = new BP_Group_Member_Query( array(
-			'group_id'       => $group_id,
-			'per_page'       => $limit,
-			'page'           => $page,
-			'group_role'     => $group_role,
-			'exclude'        => $exclude,
-			'type'           => 'last_modified',
+			'group_id'       => $r['group_id'],
+			'per_page'       => $r['per_page'],
+			'page'           => $r['page'],
+			'group_role'     => $r['group_role'],
+			'exclude'        => $r['exclude'],
+			'search_terms'   => $r['search_terms'],
+			'type'           => $r['type'],
 		) );
 
 		// Structure the return value as expected by the template functions
@@ -453,35 +504,37 @@ function groups_get_total_member_count( $group_id ) {
 function groups_get_groups( $args = '' ) {
 
 	$defaults = array(
-		'type'            => false,    // active, newest, alphabetical, random, popular, most-forum-topics or most-forum-posts
-		'order'           => 'DESC',   // 'ASC' or 'DESC'
-		'orderby'         => 'date_created', // date_created, last_activity, total_member_count, name, random
-		'user_id'         => false,    // Pass a user_id to limit to only groups that this user is a member of
-		'include'         => false,    // Only include these specific groups (group_ids)
-		'exclude'         => false,    // Do not include these specific groups (group_ids)
-		'search_terms'    => false,    // Limit to groups that match these search terms
-		'meta_query'      => false,    // Filter by groupmeta. See WP_Meta_Query for syntax
-		'show_hidden'     => false,    // Show hidden groups to non-admins
-		'per_page'        => 20,       // The number of results to return per page
-		'page'            => 1,        // The page to return if limiting per page
-		'populate_extras' => true,     // Fetch meta such as is_banned and is_member
+		'type'              => false,    // active, newest, alphabetical, random, popular, most-forum-topics or most-forum-posts
+		'order'             => 'DESC',   // 'ASC' or 'DESC'
+		'orderby'           => 'date_created', // date_created, last_activity, total_member_count, name, random
+		'user_id'           => false,    // Pass a user_id to limit to only groups that this user is a member of
+		'include'           => false,    // Only include these specific groups (group_ids)
+		'exclude'           => false,    // Do not include these specific groups (group_ids)
+		'search_terms'      => false,    // Limit to groups that match these search terms
+		'meta_query'        => false,    // Filter by groupmeta. See WP_Meta_Query for syntax
+		'show_hidden'       => false,    // Show hidden groups to non-admins
+		'per_page'          => 20,       // The number of results to return per page
+		'page'              => 1,        // The page to return if limiting per page
+		'populate_extras'   => true,     // Fetch meta such as is_banned and is_member
+		'update_meta_cache' => true,   // Pre-fetch groupmeta for queried groups
 	);
 
 	$r = wp_parse_args( $args, $defaults );
 
 	$groups = BP_Groups_Group::get( array(
-		'type'            => $r['type'],
-		'user_id'         => $r['user_id'],
-		'include'         => $r['include'],
-		'exclude'         => $r['exclude'],
-		'search_terms'    => $r['search_terms'],
-		'meta_query'      => $r['meta_query'],
-		'show_hidden'     => $r['show_hidden'],
-		'per_page'        => $r['per_page'],
-		'page'            => $r['page'],
-		'populate_extras' => $r['populate_extras'],
-		'order'           => $r['order'],
-		'orderby'         => $r['orderby'],
+		'type'              => $r['type'],
+		'user_id'           => $r['user_id'],
+		'include'           => $r['include'],
+		'exclude'           => $r['exclude'],
+		'search_terms'      => $r['search_terms'],
+		'meta_query'        => $r['meta_query'],
+		'show_hidden'       => $r['show_hidden'],
+		'per_page'          => $r['per_page'],
+		'page'              => $r['page'],
+		'populate_extras'   => $r['populate_extras'],
+		'update_meta_cache' => $r['update_meta_cache'],
+		'order'             => $r['order'],
+		'orderby'           => $r['orderby'],
 	) );
 
 	return apply_filters_ref_array( 'groups_get_groups', array( &$groups, &$r ) );
@@ -638,6 +691,22 @@ function groups_get_invites_for_user( $user_id = 0, $limit = false, $page = fals
 	return BP_Groups_Member::get_invites( $user_id, $limit, $page, $exclude );
 }
 
+/**
+ * Gets the total group invite count for a user.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $user_id The user ID
+ * @return int
+ */
+function groups_get_invite_count_for_user( $user_id = 0 ) {
+	if ( empty( $user_id ) ) {
+		$user_id = bp_loggedin_user_id();
+	}
+
+	return BP_Groups_Member::get_invite_count_for_user( $user_id );
+}
+
 function groups_invite_user( $args = '' ) {
 
 	$defaults = array(
@@ -654,7 +723,12 @@ function groups_invite_user( $args = '' ) {
 	if ( empty( $user_id ) || empty( $group_id ) )
 		return false;
 
-	if ( !groups_is_user_member( $user_id, $group_id ) && !groups_check_user_has_invite( $user_id, $group_id, 'all' ) ) {
+	// if the user has already requested membership, accept the request
+	if ( $membership_id = groups_check_for_membership_request( $user_id, $group_id ) ) {
+		groups_accept_membership_request( $membership_id, $user_id, $group_id );
+
+	// Otherwise, create a new invitation
+	} else if ( ! groups_is_user_member( $user_id, $group_id ) && ! groups_check_user_has_invite( $user_id, $group_id, 'all' ) ) {
 		$invite                = new BP_Groups_Member;
 		$invite->group_id      = $group_id;
 		$invite->user_id       = $user_id;
@@ -691,16 +765,17 @@ function groups_uninvite_user( $user_id, $group_id ) {
  * @return bool True when the user is a member of the group, otherwise false
  */
 function groups_accept_invite( $user_id, $group_id ) {
-	global $bp;
 
 	// If the user is already a member (because BP at one point allowed two invitations to
 	// slip through), delete all existing invitations/requests and return true
 	if ( groups_is_user_member( $user_id, $group_id ) ) {
-		if ( groups_check_user_has_invite( $user_id, $group_id ) )
+		if ( groups_check_user_has_invite( $user_id, $group_id ) ) {
 			groups_delete_invite( $user_id, $group_id );
+		}
 
-		if ( groups_check_for_membership_request( $user_id, $group_id ) )
+		if ( groups_check_for_membership_request( $user_id, $group_id ) ) {
 			groups_delete_membership_request( $user_id, $group_id );
+		}
 
 		return true;
 	}
@@ -708,24 +783,25 @@ function groups_accept_invite( $user_id, $group_id ) {
 	$member = new BP_Groups_Member( $user_id, $group_id );
 	$member->accept_invite();
 
-	if ( !$member->save() )
+	if ( !$member->save() ) {
 		return false;
+	}
 
 	// Remove request to join
-	if ( $member->check_for_membership_request( $user_id, $group_id ) )
+	if ( $member->check_for_membership_request( $user_id, $group_id ) ) {
 		$member->delete_request( $user_id, $group_id );
+	}
 
 	// Modify group meta
 	groups_update_groupmeta( $group_id, 'last_activity', bp_core_current_time() );
 
-	bp_core_delete_notifications_by_item_id( $user_id, $group_id, $bp->groups->id, 'group_invite' );
-
 	do_action( 'groups_accept_invite', $user_id, $group_id );
+
 	return true;
 }
 
 function groups_reject_invite( $user_id, $group_id ) {
-	if ( !BP_Groups_Member::delete( $user_id, $group_id ) )
+	if ( ! BP_Groups_Member::delete( $user_id, $group_id ) )
 		return false;
 
 	do_action( 'groups_reject_invite', $user_id, $group_id );
@@ -734,14 +810,12 @@ function groups_reject_invite( $user_id, $group_id ) {
 }
 
 function groups_delete_invite( $user_id, $group_id ) {
-	global $bp;
-
-	$delete = BP_Groups_Member::delete_invite( $user_id, $group_id );
+	if ( ! BP_Groups_Member::delete_invite( $user_id, $group_id ) )
+		return false;
 
-	if ( $delete )
-		bp_core_delete_notifications_by_item_id( $user_id, $group_id, $bp->groups->id, 'group_invite' );
+	do_action( 'groups_delete_invite', $user_id, $group_id );
 
-	return $delete;
+	return true;
 }
 
 function groups_send_invites( $user_id, $group_id ) {
@@ -872,6 +946,12 @@ function groups_send_membership_request( $requesting_user_id, $group_id ) {
 	if ( groups_is_user_member( $requesting_user_id, $group_id ) || groups_is_user_banned( $requesting_user_id, $group_id ) )
 		return false;
 
+	// Check if the user is already invited - if so, simply accept invite
+	if ( groups_check_user_has_invite( $requesting_user_id, $group_id ) ) {
+		groups_accept_invite( $requesting_user_id, $group_id );
+		return true;
+	}
+
 	$requesting_user                = new BP_Groups_Member;
 	$requesting_user->group_id      = $group_id;
 	$requesting_user->user_id       = $requesting_user_id;
@@ -899,46 +979,34 @@ function groups_send_membership_request( $requesting_user_id, $group_id ) {
 
 function groups_accept_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
 
-	if ( !empty( $user_id ) && !empty( $group_id ) )
+	if ( !empty( $user_id ) && !empty( $group_id ) ) {
 		$membership = new BP_Groups_Member( $user_id, $group_id );
-	else
+	} else {
 		$membership = new BP_Groups_Member( false, false, $membership_id );
+	}
 
 	$membership->accept_request();
 
-	if ( !$membership->save() )
+	if ( !$membership->save() ) {
 		return false;
+	}
 
 	// Check if the user has an outstanding invite, if so delete it.
-	if ( groups_check_user_has_invite( $membership->user_id, $membership->group_id ) )
+	if ( groups_check_user_has_invite( $membership->user_id, $membership->group_id ) ) {
 		groups_delete_invite( $membership->user_id, $membership->group_id );
+	}
 
-	// Record this in activity streams
-	$group = groups_get_group( array( 'group_id' => $membership->group_id ) );
-
-	groups_record_activity( array(
-		'action'  => apply_filters_ref_array( 'groups_activity_membership_accepted_action', array( sprintf( __( '%1$s joined the group %2$s', 'buddypress'), bp_core_get_userlink( $membership->user_id ), '<a href="' . bp_get_group_permalink( $group ) . '">' . esc_attr( $group->name ) . '</a>' ), $membership->user_id, &$group ) ),
-		'type'    => 'joined_group',
-		'item_id' => $membership->group_id,
-		'user_id' => $membership->user_id
-	) );
-
-	// Send a notification to the user.
-	groups_notification_membership_request_completed( $membership->user_id, $membership->group_id, true );
-
-	do_action( 'groups_membership_accepted', $membership->user_id, $membership->group_id );
+	do_action( 'groups_membership_accepted', $membership->user_id, $membership->group_id, true );
 
 	return true;
 }
 
 function groups_reject_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
-	if ( !$membership = groups_delete_membership_request( $membership_id, $user_id, $group_id ) )
+	if ( !$membership = groups_delete_membership_request( $membership_id, $user_id, $group_id ) ) {
 		return false;
+	}
 
-	// Send a notification to the user.
-	groups_notification_membership_request_completed( $membership->user_id, $membership->group_id, false );
-
-	do_action( 'groups_membership_rejected', $membership->user_id, $membership->group_id );
+	do_action( 'groups_membership_rejected', $membership->user_id, $membership->group_id, false );
 
 	return true;
 }
@@ -975,104 +1043,110 @@ function groups_accept_all_pending_membership_requests( $group_id ) {
 
 /*** Group Meta ****************************************************/
 
-function groups_delete_groupmeta( $group_id, $meta_key = false, $meta_value = false ) {
-	global $wpdb, $bp;
-
-	if ( !is_numeric( $group_id ) )
-		return false;
-
-	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-	if ( is_array( $meta_value ) || is_object( $meta_value ) )
-		$meta_value = serialize($meta_value);
-
-	$meta_value = trim( $meta_value );
-
-	if ( !$meta_key )
-		$wpdb->query( $wpdb->prepare( "DELETE FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d", $group_id ) );
-	else if ( $meta_value )
-		$wpdb->query( $wpdb->prepare( "DELETE FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d AND meta_key = %s AND meta_value = %s", $group_id, $meta_key, $meta_value ) );
-	else
-		$wpdb->query( $wpdb->prepare( "DELETE FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d AND meta_key = %s", $group_id, $meta_key ) );
-
-	// Delete the cached object
-	wp_cache_delete( 'bp_groups_groupmeta_' . $group_id . '_' . $meta_key, 'bp' );
-
-	return true;
-}
-
-function groups_get_groupmeta( $group_id, $meta_key = '') {
-	global $wpdb, $bp;
-
-	$group_id = (int) $group_id;
-
-	if ( !$group_id )
-		return false;
+/**
+ * Delete metadata for a group.
+ *
+ * @param int $group_id ID of the group.
+ * @param string $meta_key The key of the row to delete.
+ * @param string $meta_value Optional. Metadata value. If specified, only delete
+ *        metadata entries with this value.
+ * @param bool $delete_all Optional. If true, delete matching metadata entries
+ *        for all groups. Default: false.
+ * @param bool $delete_all Optional. If true, delete matching metadata entries
+ * 	  for all objects, ignoring the specified group_id. Otherwise, only
+ * 	  delete matching metadata entries for the specified group.
+ * 	  Default: false.
+ * @return bool True on success, false on failure.
+ */
+function groups_delete_groupmeta( $group_id, $meta_key = false, $meta_value = false, $delete_all = false ) {
+	global $wpdb;
 
-	if ( !empty($meta_key) ) {
-		$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
+	// Legacy - if no meta_key is passed, delete all for the item
+	if ( empty( $meta_key ) ) {
+		$keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$wpdb->groupmeta} WHERE group_id = %d", $group_id ) );
 
-		$metas = wp_cache_get( 'bp_groups_groupmeta_' . $group_id . '_' . $meta_key, 'bp' );
-		if ( false === $metas ) {
-			$metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d AND meta_key = %s", $group_id, $meta_key ) );
-			wp_cache_set( 'bp_groups_groupmeta_' . $group_id . '_' . $meta_key, $metas, 'bp' );
-		}
+		// With no meta_key, ignore $delete_all
+		$delete_all = false;
 	} else {
-		$metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d", $group_id ) );
+		$keys = array( $meta_key );
 	}
 
-	if ( empty( $metas ) ) {
-		if ( empty( $meta_key ) )
-			return array();
-		else
-			return '';
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+
+	foreach ( $keys as $key ) {
+		$retval = delete_metadata( 'group', $group_id, $key, $meta_value, $delete_all );
 	}
 
-	$metas = array_map( 'maybe_unserialize', (array) $metas );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	if ( 1 == count( $metas ) )
-		return $metas[0];
-	else
-		return $metas;
+	return $retval;
 }
 
-function groups_update_groupmeta( $group_id, $meta_key, $meta_value ) {
-	global $wpdb, $bp;
-
-	if ( !is_numeric( $group_id ) )
-		return false;
-
-	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-	if ( is_string( $meta_value ) )
-		$meta_value = stripslashes( esc_sql( $meta_value ) );
+/**
+ * Get a piece of group metadata.
+ *
+ * @param int $group_id ID of the group.
+ * @param string $meta_key Metadata key.
+ * @param bool $single Optional. If true, return only the first value of the
+ *        specified meta_key. This parameter has no effect if meta_key is
+ *        empty.
+ * @return mixed Metadata value.
+ */
+function groups_get_groupmeta( $group_id, $meta_key = '', $single = true ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = get_metadata( 'group', $group_id, $meta_key, $single );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	$meta_value = maybe_serialize( $meta_value );
+	return $retval;
+}
 
-	$cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d AND meta_key = %s", $group_id, $meta_key ) );
+/**
+ * Update a piece of group metadata.
+ *
+ * @param int $group_id ID of the group.
+ * @param string $meta_key Metadata key.
+ * @param mixed $meta_value Value to store.
+ * @param mixed $prev_value Optional. If specified, only update existing
+ *        metadata entries with the specified value. Otherwise, update all
+ *        entries.
+ * @return bool|int Returns false on failure. On successful update of existing
+ *         metadata, returns true. On successful creation of new metadata,
+ *         returns the integer ID of the new metadata row.
+ */
+function groups_update_groupmeta( $group_id, $meta_key, $meta_value, $prev_value = '' ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = update_metadata( 'group', $group_id, $meta_key, $meta_value, $prev_value );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	if ( !$cur )
-		$wpdb->query( $wpdb->prepare( "INSERT INTO " . $bp->groups->table_name_groupmeta . " ( group_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $group_id, $meta_key, $meta_value ) );
-	else if ( $cur->meta_value != $meta_value )
-		$wpdb->query( $wpdb->prepare( "UPDATE " . $bp->groups->table_name_groupmeta . " SET meta_value = %s WHERE group_id = %d AND meta_key = %s", $meta_value, $group_id, $meta_key ) );
-	else
-		return false;
+	return $retval;
+}
 
-	// Update the cached object and recache
-	wp_cache_set( 'bp_groups_groupmeta_' . $group_id . '_' . $meta_key, $meta_value, 'bp' );
+/**
+ * Add a piece of group metadata.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $group_id ID of the group.
+ * @param string $meta_key Metadata key.
+ * @param mixed $meta_value Metadata value.
+ * @param bool $unique. Optional. Whether to enforce a single metadata value
+ *        for the given key. If true, and the object already has a value for
+ *        the key, no change will be made. Default: false.
+ * @return int|bool The meta ID on successful update, false on failure.
+ */
+function groups_add_groupmeta( $group_id, $meta_key, $meta_value, $unique = false ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	$retval = add_metadata( 'group', $group_id, $meta_key, $meta_value, $unique );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	return true;
+	return $retval;
 }
 
 /*** Group Cleanup Functions ****************************************************/
 
 function groups_remove_data_for_user( $user_id ) {
-	global $bp;
-
 	BP_Groups_Member::delete_all_for_user( $user_id );
 
-	bp_core_delete_notifications_from_user( $user_id, $bp->groups->id, 'new_membership_request' );
-
 	do_action( 'groups_remove_data_for_user', $user_id );
 }
 add_action( 'wpmu_delete_user',  'groups_remove_data_for_user' );
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-loader.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-loader.php
index cf582b6718d79eb84d7c4df48664a2a828954a20..08edbffae020b30c396f1ec7633bc512575f46d5 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-loader.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-loader.php
@@ -77,11 +77,14 @@ class BP_Groups_Component extends BP_Component {
 	 *
 	 * @since BuddyPress (1.5)
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'groups',
 			__( 'User Groups', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 70
+			)
 		);
 	}
 
@@ -118,10 +121,9 @@ class BP_Groups_Component extends BP_Component {
 	 * backwards compatibility.
 	 *
 	 * @since BuddyPress (1.5)
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_globals( $args = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		// Define a slug, if necessary
 		if ( !defined( 'BP_GROUPS_SLUG' ) )
@@ -134,18 +136,25 @@ class BP_Groups_Component extends BP_Component {
 			'table_name_groupmeta' => $bp->table_prefix . 'bp_groups_groupmeta'
 		);
 
+		// Metadata tables for groups component
+		$meta_tables = array(
+			'group' => $bp->table_prefix . 'bp_groups_groupmeta',
+		);
+
 		// All globals for groups component.
 		// Note that global_tables is included in this array.
-		$globals = array(
+		$args = array(
 			'slug'                  => BP_GROUPS_SLUG,
 			'root_slug'             => isset( $bp->pages->groups->slug ) ? $bp->pages->groups->slug : BP_GROUPS_SLUG,
 			'has_directory'         => true,
+			'directory_title'       => _x( 'Groups', 'component directory title', 'buddypress' ),
 			'notification_callback' => 'groups_format_notifications',
 			'search_string'         => __( 'Search Groups...', 'buddypress' ),
-			'global_tables'         => $global_tables
+			'global_tables'         => $global_tables,
+			'meta_tables'           => $meta_tables,
 		);
 
-		parent::setup_globals( $globals );
+		parent::setup_globals( $args );
 
 		/** Single Group Globals **********************************************/
 
@@ -154,7 +163,16 @@ class BP_Groups_Component extends BP_Component {
 
 			$bp->is_single_item  = true;
 			$current_group_class = apply_filters( 'bp_groups_current_group_class', 'BP_Groups_Group' );
-			$this->current_group = apply_filters( 'bp_groups_current_group_object', new $current_group_class( $group_id ) );
+
+			if ( $current_group_class == 'BP_Groups_Group' ) {
+				$this->current_group = groups_get_group( array(
+					'group_id'        => $group_id,
+					'populate_extras' => true,
+				) );
+
+			} else {
+				$this->current_group = apply_filters( 'bp_groups_current_group_object', new $current_group_class( $group_id ) );
+			}
 
 			// When in a single group, the first action is bumped down one because of the
 			// group name, so we need to adjust this and set the group name to current_item.
@@ -338,12 +356,18 @@ class BP_Groups_Component extends BP_Component {
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
 
-		// Define local variables
-		$sub_nav = array();
+		// Only grab count if we're on a user page
+		if ( bp_is_user() ) {
+			$count    = bp_get_total_group_count_for_user();
+			$class    = ( 0 === $count ) ? 'no-count' : 'count';
+			$nav_name = sprintf( __( 'Groups <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), number_format_i18n( $count ) );
+		} else {
+			$nav_name = __( 'Groups', 'buddypress' );
+		}
 
 		// Add 'Groups' to the main navigation
 		$main_nav = array(
-			'name'                => sprintf( __( 'Groups <span>%d</span>', 'buddypress' ), bp_get_total_group_count_for_user() ),
+			'name'                => $nav_name,
 			'slug'                => $this->slug,
 			'position'            => 70,
 			'screen_function'     => 'groups_screen_my_groups',
@@ -416,13 +440,16 @@ class BP_Groups_Component extends BP_Component {
 				'item_css_id'     => 'home'
 			);
 
-			// If this is a private group, and the user is not a member, show a "Request Membership" nav item.
+			// If this is a private group, and the user is not a
+			// member and does not have an outstanding invitation,
+			// show a "Request Membership" nav item.
 			if ( is_user_logged_in() &&
-				 !bp_current_user_can( 'bp_moderate' ) &&
-				 !$this->current_group->is_user_member &&
-				 !groups_check_for_membership_request( bp_loggedin_user_id(), $this->current_group->id ) &&
-				 $this->current_group->status == 'private'
+				 ! $this->current_group->is_user_member &&
+				 ! groups_check_for_membership_request( bp_loggedin_user_id(), $this->current_group->id ) &&
+				 $this->current_group->status == 'private' &&
+				 ! groups_check_user_has_invite( bp_loggedin_user_id(), $this->current_group->id )
 				) {
+
 				$sub_nav[] = array(
 					'name'               => __( 'Request Membership', 'buddypress' ),
 					'slug'               => 'request-membership',
@@ -488,22 +515,18 @@ class BP_Groups_Component extends BP_Component {
 			parent::setup_nav( $main_nav, $sub_nav );
 		}
 
-		if ( isset( $this->current_group->user_has_access ) )
+		if ( isset( $this->current_group->user_has_access ) ) {
 			do_action( 'groups_setup_nav', $this->current_group->user_has_access );
-		else
+		} else {
 			do_action( 'groups_setup_nav');
+		}
 	}
 
 	/**
 	 * Set up the Toolbar
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_admin_bar( $wp_admin_nav = array() ) {
-		global $bp;
-
-		// Prevent debug notices
-		$wp_admin_nav = array();
+		$bp = buddypress();
 
 		// Menus for logged in user
 		if ( is_user_logged_in() ) {
@@ -513,13 +536,13 @@ class BP_Groups_Component extends BP_Component {
 			$groups_link = trailingslashit( $user_domain . $this->slug );
 
 			// Pending group invites
-			$count   = groups_get_invites_for_user( bp_loggedin_user_id() );
+			$count   = groups_get_invite_count_for_user();
 			$title   = __( 'Groups',             'buddypress' );
 			$pending = __( 'No Pending Invites', 'buddypress' );
 
 			if ( !empty( $count['total'] ) ) {
-				$title   = sprintf( __( 'Groups <span class="count">%s</span>',          'buddypress' ), $count['total'] );
-				$pending = sprintf( __( 'Pending Invites <span class="count">%s</span>', 'buddypress' ), $count['total'] );
+				$title   = sprintf( __( 'Groups <span class="count">%s</span>',          'buddypress' ), $count );
+				$pending = sprintf( __( 'Pending Invites <span class="count">%s</span>', 'buddypress' ), $count );
 			}
 
 			// Add the "My Account" sub menus
@@ -562,20 +585,16 @@ class BP_Groups_Component extends BP_Component {
 
 	/**
 	 * Sets up the title for pages and <title>
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
-	function setup_title() {
-		global $bp;
+	public function setup_title() {
+		$bp = buddypress();
 
 		if ( bp_is_groups_component() ) {
 
 			if ( bp_is_my_profile() && !bp_is_single_item() ) {
-
 				$bp->bp_options_title = __( 'Memberships', 'buddypress' );
 
 			} else if ( !bp_is_my_profile() && !bp_is_single_item() ) {
-
 				$bp->bp_options_avatar = bp_core_fetch_avatar( array(
 					'item_id' => bp_displayed_user_id(),
 					'type'    => 'thumb',
@@ -594,8 +613,9 @@ class BP_Groups_Component extends BP_Component {
 					'avatar_dir' => 'group-avatars',
 					'alt'        => __( 'Group Avatar', 'buddypress' )
 				) );
+
 				if ( empty( $bp->bp_options_avatar ) ) {
-					$bp->bp_options_avatar = '<img src="' . esc_attr( $group->avatar_full ) . '" class="avatar" alt="' . esc_attr( $group->name ) . '" />';
+					$bp->bp_options_avatar = '<img src="' . esc_url( bp_core_avatar_default_thumb() ) . '" alt="' . esc_attr__( 'No Group Avatar', 'buddypress' ) . '" class="avatar" />';
 				}
 			}
 		}
@@ -606,8 +626,6 @@ class BP_Groups_Component extends BP_Component {
 
 
 function bp_setup_groups() {
-	global $bp;
-
-	$bp->groups = new BP_Groups_Component();
+	buddypress()->groups = new BP_Groups_Component();
 }
 add_action( 'bp_setup_components', 'bp_setup_groups', 6 );
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-notifications.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-notifications.php
index 37d2f56be5b63a0af1885876783030c68c8f9b46..8f50541c50947270f07c5f0fb458984687930196 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-notifications.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-notifications.php
@@ -13,6 +13,8 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/** Emails ********************************************************************/
+
 function groups_notification_group_updated( $group_id ) {
 
 	$group    = groups_get_group( array( 'group_id' => $group_id ) );
@@ -56,19 +58,33 @@ To view the group: %2$s
 
 function groups_notification_new_membership_request( $requesting_user_id, $admin_id, $group_id, $membership_id ) {
 
-	bp_core_add_notification( $requesting_user_id, $admin_id, 'groups', 'new_membership_request', $group_id );
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_add_notification( array(
+			'user_id'           => $admin_id,
+			'item_id'           => $group_id,
+			'secondary_item_id' => $requesting_user_id,
+			'component_name'    => buddypress()->groups->id,
+			'component_action'  => 'new_membership_request'
+		) );
+	}
 
 	if ( 'no' == bp_get_user_meta( $admin_id, 'notification_groups_membership_request', true ) )
 		return false;
 
+	// Username of the user requesting a membership: %1$s in mail
 	$requesting_user_name = bp_core_get_user_displayname( $requesting_user_id );
 	$group                = groups_get_group( array( 'group_id' => $group_id ) );
 
+	// Group Administrator user's data
 	$ud             = bp_core_get_core_userdata( $admin_id );
 	$group_requests = bp_get_group_permalink( $group ) . 'admin/membership-requests';
+
+	// Link to the user's profile who's requesting a membership: %3$s in mail
 	$profile_link   = bp_core_get_user_domain( $requesting_user_id );
+
 	$settings_slug  = function_exists( 'bp_get_settings_slug' ) ? bp_get_settings_slug() : 'settings';
-	$settings_link  = bp_core_get_user_domain( $requesting_user_id ) . $settings_slug . '/notifications/';
+	// Link to the group administrator email settings: %s in "disable notifications" part of the email
+	$settings_link  = bp_core_get_user_domain( $admin_id ) . $settings_slug . '/notifications/';
 
 	// Set up and send the message
 	$to       = $ud->user_email;
@@ -105,10 +121,17 @@ To view %4$s\'s profile: %5$s
 function groups_notification_membership_request_completed( $requesting_user_id, $group_id, $accepted = true ) {
 
 	// Post a screen notification first.
-	if ( $accepted )
-		bp_core_add_notification( $group_id, $requesting_user_id, 'groups', 'membership_request_accepted' );
-	else
-		bp_core_add_notification( $group_id, $requesting_user_id, 'groups', 'membership_request_rejected' );
+	if ( bp_is_active( 'notifications' ) ) {
+
+		$type = ! empty( $accepted ) ? 'membership_request_accepted' : 'membership_request_rejected' ;
+
+		bp_notifications_add_notification( array(
+			'user_id'           => $requesting_user_id,
+			'item_id'           => $group_id,
+			'component_name'    => buddypress()->groups->id,
+			'component_action'  => $type
+		) );
+	}
 
 	if ( 'no' == bp_get_user_meta( $requesting_user_id, 'notification_membership_request_completed', true ) )
 		return false;
@@ -159,6 +182,8 @@ To submit another request please log in and visit: %2$s
 
 	do_action( 'bp_groups_sent_membership_approved_email', $requesting_user_id, $subject, $message, $group_id );
 }
+add_action( 'groups_membership_accepted', 'groups_notification_membership_request_completed', 10, 3 );
+add_action( 'groups_membership_rejected', 'groups_notification_membership_request_completed', 10, 3 );
 
 function groups_notification_promoted_member( $user_id, $group_id ) {
 
@@ -171,7 +196,16 @@ function groups_notification_promoted_member( $user_id, $group_id ) {
 	}
 
 	// Post a screen notification first.
-	bp_core_add_notification( $group_id, $user_id, 'groups', $type );
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_add_notification( array(
+			'user_id'           => $user_id,
+			'item_id'           => $group_id,
+			'component_name'    => buddypress()->groups->id,
+			'component_action'  => $type,
+			'date_notified'     => bp_core_current_time(),
+			'is_new'            => 1,
+		) );
+	}
 
 	if ( 'no' == bp_get_user_meta( $user_id, 'notification_groups_admin_promotion', true ) )
 		return false;
@@ -222,7 +256,14 @@ function groups_notification_group_invites( &$group, &$member, $inviter_user_id
 		$invited_user_id = $member->user_id;
 
 		// Post a screen notification first.
-		bp_core_add_notification( $group->id, $invited_user_id, 'groups', 'group_invite' );
+		if ( bp_is_active( 'notifications' ) ) {
+			bp_notifications_add_notification( array(
+				'user_id'           => $invited_user_id,
+				'item_id'           => $group->id,
+				'component_name'    => buddypress()->groups->id,
+				'component_action'  => 'group_invite'
+			) );
+		}
 
 		if ( 'no' == bp_get_user_meta( $invited_user_id, 'notification_groups_invite', true ) )
 			return false;
@@ -264,3 +305,348 @@ To view %5$s\'s profile visit: %6$s
 		do_action( 'bp_groups_sent_invited_email', $invited_user_id, $subject, $message, $group );
 	}
 }
+
+/** Notifications *************************************************************/
+
+/**
+ * Format the BuddyBar/Toolbar notifications for the Groups component
+ *
+ * @since BuddyPress (1.0)
+ * @param string $action The kind of notification being rendered
+ * @param int $item_id The primary item id
+ * @param int $secondary_item_id The secondary item id
+ * @param int $total_items The total number of messaging-related notifications waiting for the user
+ * @param string $format 'string' for BuddyBar-compatible notifications; 'array' for WP Toolbar
+ */
+function groups_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
+
+	switch ( $action ) {
+		case 'new_membership_request':
+			$group_id = $item_id;
+			$requesting_user_id = $secondary_item_id;
+
+			$group = groups_get_group( array( 'group_id' => $group_id ) );
+			$group_link = bp_get_group_permalink( $group );
+
+			// Set up the string and the filter
+			// Because different values are passed to the filters, we'll return the
+			// values inline
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( '%1$d new membership requests for the group "%2$s"', 'buddypress' ), (int) $total_items, $group->name );
+				$filter = 'bp_groups_multiple_new_membership_requests_notification';
+				$notification_link = $group_link . 'admin/membership-requests/?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Group Membership Requests', 'buddypress' ) . '">' . $text . '</a>', $group_link, $total_items, $group->name, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $group_link, $total_items, $group->name, $text, $notification_link );
+				}
+			} else {
+				$user_fullname = bp_core_get_user_displayname( $requesting_user_id );
+				$text = sprintf( __( '%s requests group membership', 'buddypress' ), $user_fullname );
+				$filter = 'bp_groups_single_new_membership_request_notification';
+				$notification_link = $group_link . 'admin/membership-requests/?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . sprintf( __( '%s requests group membership', 'buddypress' ), $user_fullname ) . '">' . $text . '</a>', $group_link, $user_fullname, $group->name, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $group_link, $user_fullname, $group->name, $text, $notification_link );
+				}
+			}
+
+			break;
+
+		case 'membership_request_accepted':
+			$group_id = $item_id;
+
+			$group = groups_get_group( array( 'group_id' => $group_id ) );
+			$group_link = bp_get_group_permalink( $group );
+
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( '%d accepted group membership requests', 'buddypress' ), (int) $total_items, $group->name );
+				$filter = 'bp_groups_multiple_membership_request_accepted_notification';
+				$notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Groups', 'buddypress' ) . '">' . $text . '</a>', $total_items, $group->name, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $total_items, $group->name, $text, $notification_link );
+				}
+			} else {
+				$text = sprintf( __( 'Membership for group "%s" accepted', 'buddypress' ), $group->name );
+				$filter = 'bp_groups_single_membership_request_accepted_notification';
+				$notification_link = $group_link . '?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $group_link, $group->name, $text, $notification_link );
+				}
+			}
+
+			break;
+
+		case 'membership_request_rejected':
+			$group_id = $item_id;
+
+			$group = groups_get_group( array( 'group_id' => $group_id ) );
+			$group_link = bp_get_group_permalink( $group );
+
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( '%d rejected group membership requests', 'buddypress' ), (int) $total_items, $group->name );
+				$filter = 'bp_groups_multiple_membership_request_rejected_notification';
+				$notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Groups', 'buddypress' ) . '">' . $text . '</a>', $total_items, $group->name );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $total_items, $group->name, $text, $notification_link );
+				}
+			} else {
+				$text = sprintf( __( 'Membership for group "%s" rejected', 'buddypress' ), $group->name );
+				$filter = 'bp_groups_single_membership_request_rejected_notification';
+				$notification_link = $group_link . '?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $group_link, $group->name, $text, $notification_link );
+				}
+			}
+
+			break;
+
+		case 'member_promoted_to_admin':
+			$group_id = $item_id;
+
+			$group = groups_get_group( array( 'group_id' => $group_id ) );
+			$group_link = bp_get_group_permalink( $group );
+
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( 'You were promoted to an admin in %d groups', 'buddypress' ), (int) $total_items );
+				$filter = 'bp_groups_multiple_member_promoted_to_admin_notification';
+				$notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Groups', 'buddypress' ) . '">' . $text . '</a>', $total_items, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $total_items, $text, $notification_link );
+				}
+			} else {
+				$text = sprintf( __( 'You were promoted to an admin in the group "%s"', 'buddypress' ), $group->name );
+				$filter = 'bp_groups_single_member_promoted_to_admin_notification';
+				$notification_link = $group_link . '?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $group_link, $group->name, $text, $notification_link );
+				}
+			}
+
+			break;
+
+		case 'member_promoted_to_mod':
+			$group_id = $item_id;
+
+			$group = groups_get_group( array( 'group_id' => $group_id ) );
+			$group_link = bp_get_group_permalink( $group );
+
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( 'You were promoted to a mod in %d groups', 'buddypress' ), (int) $total_items );
+				$filter = 'bp_groups_multiple_member_promoted_to_mod_notification';
+				$notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Groups', 'buddypress' ) . '">' . $text . '</a>', $total_items, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $total_items, $text, $notification_link );
+				}
+			} else {
+				$text = sprintf( __( 'You were promoted to a mod in the group "%s"', 'buddypress' ), $group->name );
+				$filter = 'bp_groups_single_member_promoted_to_mod_notification';
+				$notification_link = $group_link . '?n=1';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $group_link, $group->name, $text, $notification_link );
+				}
+			}
+
+			break;
+
+		case 'group_invite':
+			$group_id = $item_id;
+			$group = groups_get_group( array( 'group_id' => $group_id ) );
+			$group_link = bp_get_group_permalink( $group );
+
+			$notification_link = bp_loggedin_user_domain() . bp_get_groups_slug() . '/invites/?n=1';
+
+			if ( (int) $total_items > 1 ) {
+				$text = sprintf( __( 'You have %d new group invitations', 'buddypress' ), (int) $total_items );
+				$filter = 'bp_groups_multiple_group_invite_notification';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '" title="' . __( 'Group Invites', 'buddypress' ) . '">' . $text . '</a>', $total_items, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $total_items, $text, $notification_link );
+				}
+			} else {
+				$text = sprintf( __( 'You have an invitation to the group: %s', 'buddypress' ), $group->name );
+				$filter = 'bp_groups_single_group_invite_notification';
+
+				if ( 'string' == $format ) {
+					return apply_filters( $filter, '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
+				} else {
+					return apply_filters( $filter, array(
+						'link' => $notification_link,
+						'text' => $text
+					), $group_link, $group->name, $text, $notification_link );
+				}
+			}
+
+			break;
+	}
+
+	do_action( 'groups_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
+
+	return false;
+}
+
+/**
+ * Remove all notifications for any member belonging to a specific group
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_groups_delete_group_delete_all_notifications( $group_id ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_delete_all_notifications_by_type( $group_id, buddypress()->groups->id );
+	}
+}
+add_action( 'groups_delete_group', 'bp_groups_delete_group_delete_all_notifications', 10 );
+
+/**
+ * When a demotion takes place, delete any corresponding promotion notifications.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_groups_delete_promotion_notifications( $user_id = 0, $group_id = 0 ) {
+	if ( bp_is_active( 'notifications' ) && ! empty( $group_id ) && ! empty( $user_id ) ) {
+		bp_notifications_delete_notifications_by_item_id( $user_id, $group_id, buddypress()->groups->id, 'member_promoted_to_admin' );
+		bp_notifications_delete_notifications_by_item_id( $user_id, $group_id, buddypress()->groups->id, 'member_promoted_to_mod' );
+	}
+}
+add_action( 'groups_demoted_member', 'bp_groups_delete_promotion_notifications', 10, 2 );
+
+/**
+ * Mark notifications read when a member accepts a group invitation
+ *
+ * @since BuddyPress (1.9.0)
+ * @param int $user_id
+ * @param int $group_id
+ */
+function bp_groups_accept_invite_mark_notifications( $user_id, $group_id ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_mark_notifications_by_item_id( $user_id, $group_id, buddypress()->groups->id, 'group_invite' );
+	}
+}
+add_action( 'groups_accept_invite', 'bp_groups_accept_invite_mark_notifications', 10, 2 );
+add_action( 'groups_reject_invite', 'bp_groups_accept_invite_mark_notifications', 10, 2 );
+add_action( 'groups_delete_invite', 'bp_groups_accept_invite_mark_notifications', 10, 2 );
+
+/**
+ * Mark notifications read when a member views their group memberships
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_groups_screen_my_groups_mark_notifications() {
+
+	// Delete group request notifications for the user
+	if ( isset( $_GET['n'] ) && bp_is_active( 'notifications' ) ) {
+
+		// Get the necessary ID's
+		$group_id = buddypress()->groups->id;
+		$user_id  = bp_loggedin_user_id();
+
+		// Mark notifications read
+		bp_notifications_mark_notifications_by_type( $user_id, $group_id, 'membership_request_accepted' );
+		bp_notifications_mark_notifications_by_type( $user_id, $group_id, 'membership_request_rejected' );
+		bp_notifications_mark_notifications_by_type( $user_id, $group_id, 'member_promoted_to_mod'      );
+		bp_notifications_mark_notifications_by_type( $user_id, $group_id, 'member_promoted_to_admin'    );
+	}
+}
+add_action( 'groups_screen_my_groups',  'bp_groups_screen_my_groups_mark_notifications', 10 );
+add_action( 'groups_screen_group_home', 'bp_groups_screen_my_groups_mark_notifications', 10 );
+
+/**
+ * Mark group invitation notifications read when a member views their invitations
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_groups_screen_invites_mark_notifications() {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_mark_notifications_by_type( bp_loggedin_user_id(), buddypress()->groups->id, 'group_invite' );
+	}
+}
+add_action( 'groups_screen_group_invites', 'bp_groups_screen_invites_mark_notifications', 10 );
+
+/**
+ * Mark group join requests read when an admin or moderator visits the group
+ * administration area.
+ *
+ * @since BuddyPress (1.9.0)
+ * @param int $group_id
+ */
+function bp_groups_screen_group_admin_requests_mark_notifications( $group_id ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_mark_notifications_by_type( bp_loggedin_user_id(), buddypress()->groups->id, 'new_membership_request' );
+	}
+}
+add_action( 'groups_screen_group_admin_requests', 'bp_groups_screen_group_admin_requests_mark_notifications', 10 );
+
+/**
+ * Delete new group membership notifications when a user is being deleted.
+ *
+ * @since BuddyPress (1.9.0)
+ * @param int $user_id
+ */
+function bp_groups_remove_data_for_user_notifications( $user_id ) {
+	if ( bp_is_active( 'notifications' ) ) {
+		bp_notifications_delete_notifications_from_user( $user_id, buddypress()->groups->id, 'new_membership_request' );
+	}
+}
+add_action( 'groups_remove_data_for_user', 'bp_groups_remove_data_for_user_notifications', 10 );
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-screens.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-screens.php
index 7d83ad923d34ef4cf1c1d0110b4582348770a6f2..c2feff5b2bd92e9233a4ec80fc58585f5531f206 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-screens.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-screens.php
@@ -15,7 +15,7 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 function groups_directory_groups_setup() {
-	if ( bp_is_groups_component() && !bp_current_action() && !bp_current_item() ) {
+	if ( bp_is_groups_directory() ) {
 		bp_update_is_directory( true, 'groups' );
 
 		do_action( 'groups_directory_groups_setup' );
@@ -27,16 +27,6 @@ add_action( 'bp_screens', 'groups_directory_groups_setup', 2 );
 
 function groups_screen_my_groups() {
 
-	$bp = buddypress();
-
-	// Delete group request notifications for the user
-	if ( isset( $_GET['n'] ) ) {
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'membership_request_accepted' );
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'membership_request_rejected' );
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'member_promoted_to_mod'      );
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'member_promoted_to_admin'    );
-	}
-
 	do_action( 'groups_screen_my_groups' );
 
 	bp_core_load_template( apply_filters( 'groups_template_my_groups', 'members/single/home' ) );
@@ -59,13 +49,18 @@ function groups_screen_group_invites() {
 			$group = groups_get_group( array( 'group_id' => $group_id ) );
 
 			groups_record_activity( array(
-				'action'  => apply_filters_ref_array( 'groups_activity_accepted_invite_action', array( sprintf( __( '%1$s joined the group %2$s', 'buddypress'), bp_core_get_userlink( bp_loggedin_user_id() ), '<a href="' . bp_get_group_permalink( $group ) . '">' . esc_attr( $group->name ) . '</a>' ), bp_loggedin_user_id(), &$group ) ),
 				'type'    => 'joined_group',
 				'item_id' => $group->id
 			) );
 		}
 
-		bp_core_redirect( trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() . '/' . bp_current_action() ) );
+		if ( isset( $_GET['redirect_to'] ) ) {
+			$redirect_to = urldecode( $_GET['redirect_to'] );
+		} else {
+			$redirect_to = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() . '/' . bp_current_action() );
+		}
+
+		bp_core_redirect( $redirect_to );
 
 	} else if ( bp_is_action_variable( 'reject' ) && is_numeric( $group_id ) ) {
 		// Check the nonce
@@ -78,11 +73,14 @@ function groups_screen_group_invites() {
 			bp_core_add_message( __( 'Group invite rejected', 'buddypress' ) );
 		}
 
-		bp_core_redirect( trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() . '/' . bp_current_action() ) );
-	}
+		if ( isset( $_GET['redirect_to'] ) ) {
+			$redirect_to = urldecode( $_GET['redirect_to'] );
+		} else {
+			$redirect_to = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() . '/' . bp_current_action() );
+		}
 
-	// Remove notifications
-	bp_core_delete_notifications_by_type( bp_loggedin_user_id(), 'groups', 'group_invite' );
+		bp_core_redirect( $redirect_to );
+	}
 
 	do_action( 'groups_screen_group_invites', $group_id );
 
@@ -91,16 +89,8 @@ function groups_screen_group_invites() {
 
 function groups_screen_group_home() {
 
-	if ( ! bp_is_single_item() )
+	if ( ! bp_is_single_item() ) {
 		return false;
-
-	$bp = buddypress();
-
-	if ( isset( $_GET['n'] ) ) {
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'membership_request_accepted' );
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'membership_request_rejected' );
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'member_promoted_to_mod'      );
-		bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'member_promoted_to_admin'    );
 	}
 
 	do_action( 'groups_screen_group_home' );
@@ -456,6 +446,49 @@ function groups_screen_group_invite() {
 	}
 }
 
+/**
+ * Process group invitation removal requests.
+ *
+ * Note that this function is only used when JS is disabled. Normally, clicking
+ * Remove Invite removes the invitation via AJAX.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function groups_remove_group_invite() {
+	if ( ! bp_is_group_invites() ) {
+		return;
+	}
+
+	if ( ! bp_is_action_variable( 'remove', 0 ) || ! is_numeric( bp_action_variable( 1 ) ) ) {
+		return;
+	}
+
+	if ( ! check_admin_referer( 'groups_invite_uninvite_user' ) ) {
+		return false;
+	}
+
+	$friend_id = intval( bp_action_variable( 1 ) );
+	$group_id  = bp_get_current_group_id();
+	$message   = __( 'Invite successfully removed', 'buddypress' );
+	$redirect  = wp_get_referer();
+	$error     = false;
+
+	if ( ! bp_groups_user_can_send_invites( $group_id ) ) {
+		$message = __( 'You are not allowed to send or remove invites', 'buddypress' );
+		$error = 'error';
+	} else if ( BP_Groups_Member::check_for_membership_request( $friend_id, $group_id ) ) {
+		$message = __( 'The member requested to join the group', 'buddypress' );
+		$error = 'error';
+	} else if ( ! groups_uninvite_user( $friend_id, $group_id ) ) {
+		$message = __( 'There was an error removing the invite', 'buddypress' );
+		$error = 'error';
+	}
+
+	bp_core_add_message( $message, $error );
+	bp_core_redirect( $redirect );
+}
+add_action( 'bp_screens', 'groups_remove_group_invite' );
+
 function groups_screen_group_request_membership() {
 	global $bp;
 
@@ -467,6 +500,15 @@ function groups_screen_group_request_membership() {
 	if ( 'private' != $bp->groups->current_group->status )
 		return false;
 
+	// If the user is already invited, accept invitation
+	if ( groups_check_user_has_invite( bp_loggedin_user_id(), $bp->groups->current_group->id ) ) {
+		if ( groups_accept_invite( bp_loggedin_user_id(), $bp->groups->current_group->id ) )
+			bp_core_add_message( __( 'Group invite accepted', 'buddypress' ) );
+		else
+			bp_core_add_message( __( 'There was an error accepting the group invitation, please try again.', 'buddypress' ), 'error' );
+		bp_core_redirect( bp_get_group_permalink( $bp->groups->current_group ) );
+	}
+
 	// If the user has submitted a request, send it.
 	if ( isset( $_POST['group-request-send']) ) {
 
@@ -563,7 +605,7 @@ function groups_screen_group_admin_settings() {
 
 		// Checked against a whitelist for security
 		$allowed_invite_status = apply_filters( 'groups_allowed_invite_status', array( 'members', 'mods', 'admins' ) );
-		$invite_status	       = in_array( $_POST['group-invite-status'], (array) $allowed_invite_status ) ? $_POST['group-invite-status'] : 'members';
+		$invite_status	       = isset( $_POST['group-invite-status'] ) && in_array( $_POST['group-invite-status'], (array) $allowed_invite_status ) ? $_POST['group-invite-status'] : 'members';
 
 		// Check the nonce
 		if ( !check_admin_referer( 'groups_edit_group_settings' ) )
@@ -649,9 +691,9 @@ function groups_screen_group_admin_avatar() {
 		);
 
 		if ( !bp_core_avatar_handle_crop( $args ) ) {
-			bp_core_add_message( __( 'There was a problem cropping the avatar.', '       buddypress' ), 'error' );
+			bp_core_add_message( __( 'There was a problem cropping the avatar.', 'buddypress' ), 'error' );
 		} else {
-			bp_core_add_message( __( 'The new group avatar was uploaded successfully.', 'buddypress' )          );
+			bp_core_add_message( __( 'The new group avatar was uploaded successfully.', 'buddypress' ) );
 		}
 	}
 
@@ -783,19 +825,18 @@ function groups_screen_group_admin_manage_members() {
 add_action( 'bp_screens', 'groups_screen_group_admin_manage_members' );
 
 function groups_screen_group_admin_requests() {
-	global $bp;
+	$bp = buddypress();
 
-	if ( 'membership-requests' != bp_get_group_current_admin_tab() )
+	if ( 'membership-requests' != bp_get_group_current_admin_tab() ) {
 		return false;
+	}
 
-	if ( ! bp_is_item_admin() || ( 'public' == $bp->groups->current_group->status ) )
+	if ( ! bp_is_item_admin() || ( 'public' == $bp->groups->current_group->status ) ) {
 		return false;
+	}
 
-	// Remove any screen notifications
-	bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->groups->id, 'new_membership_request' );
-
-	$request_action = (string)bp_action_variable( 1 );
-	$membership_id  = (int)bp_action_variable( 2 );
+	$request_action = (string) bp_action_variable( 1 );
+	$membership_id  = (int) bp_action_variable( 2 );
 
 	if ( !empty( $request_action ) && !empty( $membership_id ) ) {
 		if ( 'accept' == $request_action && is_numeric( $membership_id ) ) {
@@ -1022,12 +1063,7 @@ class BP_Groups_Theme_Compat {
 	 */
 	public function directory_dummy_post() {
 
-		// Title based on ability to create groups
-		if ( is_user_logged_in() && bp_user_can_create_groups() ) {
-			$title = __( 'Groups', 'buddypress' ) . '&nbsp;<a class="button bp-title-button" href="' . trailingslashit( bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create' ) . '">' . __( 'Create a Group', 'buddypress' ) . '</a>';
-		} else {
-			$title = __( 'Groups', 'buddypress' );
-		}
+		$title = apply_filters( 'bp_groups_directory_header', bp_get_directory_title( 'groups' ) );
 
 		bp_theme_compat_reset_post( array(
 			'ID'             => 0,
@@ -1037,7 +1073,7 @@ class BP_Groups_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => 'bp_group',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
@@ -1048,7 +1084,7 @@ class BP_Groups_Theme_Compat {
 	 * @since BuddyPress (1.7)
 	 */
 	public function directory_content() {
-		bp_buffer_template_part( 'groups/index' );
+		return bp_buffer_template_part( 'groups/index', null, false );
 	}
 
 	/** Create ****************************************************************/
@@ -1083,12 +1119,7 @@ class BP_Groups_Theme_Compat {
 	 */
 	public function create_dummy_post() {
 
-		// Title based on ability to create groups
-		if ( is_user_logged_in() && bp_user_can_create_groups() ) {
-			$title = '<a class="button" href="' . trailingslashit( bp_get_root_domain() . '/' . bp_get_groups_root_slug() ) . '">' . __( 'Groups', 'buddypress' ) . '</a>&nbsp;' . __( 'Create a Group', 'buddypress' );
-		} else {
-			$title = __( 'Groups', 'buddypress' );
-		}
+		$title = __( 'Groups', 'buddypress' );
 
 		bp_theme_compat_reset_post( array(
 			'ID'             => 0,
@@ -1098,7 +1129,7 @@ class BP_Groups_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => 'bp_group',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
@@ -1109,13 +1140,13 @@ class BP_Groups_Theme_Compat {
 	 * @since BuddyPress (1.7)
 	 */
 	public function create_content() {
-		bp_buffer_template_part( 'groups/create' );
+		return bp_buffer_template_part( 'groups/create', null, false );
 	}
 
 	/** Single ****************************************************************/
 
 	/**
-	 * Add custom template hierarchy to theme compat for group pages. 
+	 * Add custom template hierarchy to theme compat for group pages.
 	 *
 	 * This is to mirror how WordPress has {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
 	 *
@@ -1158,7 +1189,7 @@ class BP_Groups_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => 'bp_group',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
@@ -1169,7 +1200,7 @@ class BP_Groups_Theme_Compat {
 	 * @since BuddyPress (1.7)
 	 */
 	public function single_content() {
-		bp_buffer_template_part( 'groups/single/home' );
+		return bp_buffer_template_part( 'groups/single/home', null, false );
 	}
 }
 new BP_Groups_Theme_Compat();
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-template.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-template.php
index fddd3086ae6c5063039b6efcd626fd2708436044..a59e6107559b7a59e878197991be4d3240e676ff 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-template.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-template.php
@@ -30,8 +30,7 @@ function bp_groups_slug() {
 	 * @since BuddyPress (1.5)
 	 */
 	function bp_get_groups_slug() {
-		global $bp;
-		return apply_filters( 'bp_get_groups_slug', $bp->groups->slug );
+		return apply_filters( 'bp_get_groups_slug', buddypress()->groups->slug );
 	}
 
 /**
@@ -54,8 +53,7 @@ function bp_groups_root_slug() {
 	 * @since BuddyPress (1.5)
 	 */
 	function bp_get_groups_root_slug() {
-		global $bp;
-		return apply_filters( 'bp_get_groups_root_slug', $bp->groups->root_slug );
+		return apply_filters( 'bp_get_groups_root_slug', buddypress()->groups->root_slug );
 	}
 
 /**
@@ -145,7 +143,8 @@ class BP_Groups_Template {
 			'exclude'         => false,
 			'search_terms'    => '',
 			'meta_query'      => false,
-			'populate_extras' => true
+			'populate_extras' => true,
+			'update_meta_cache' => true,
 		);
 
 		$r = wp_parse_args( $args, $defaults );
@@ -161,22 +160,23 @@ class BP_Groups_Template {
 			$this->groups = groups_get_invites_for_user( $user_id, $this->pag_num, $this->pag_page, $exclude );
 		} else if ( 'single-group' == $type ) {
 			$group           = new stdClass;
-			$group->group_id = BP_Groups_Group::get_id_from_slug( $slug );
+			$group->group_id = bp_get_current_group_id();
 			$this->groups    = array( $group );
 		} else {
 			$this->groups = groups_get_groups( array(
-				'type'            => $type,
-				'order'           => $order,
-				'orderby'         => $orderby,
-				'per_page'        => $this->pag_num,
-				'page'            => $this->pag_page,
-				'user_id'         => $user_id,
-				'search_terms'    => $search_terms,
-				'meta_query'      => $meta_query,
-				'include'         => $include,
-				'exclude'         => $exclude,
-				'populate_extras' => $populate_extras,
-				'show_hidden'     => $show_hidden
+				'type'              => $type,
+				'order'             => $order,
+				'orderby'           => $orderby,
+				'per_page'          => $this->pag_num,
+				'page'              => $this->pag_page,
+				'user_id'           => $user_id,
+				'search_terms'      => $search_terms,
+				'meta_query'        => $meta_query,
+				'include'           => $include,
+				'exclude'           => $exclude,
+				'populate_extras'   => $populate_extras,
+				'update_meta_cache' => $update_meta_cache,
+				'show_hidden'       => $show_hidden
 			) );
 		}
 
@@ -261,7 +261,7 @@ class BP_Groups_Template {
 		$this->group       = $this->next_group();
 
 		if ( $this->single_group )
-			$this->group = groups_get_group( array( 'group_id' => $this->group->group_id ) );
+			$this->group = groups_get_current_group();
 
 		if ( 0 == $this->current_group ) // loop has just started
 			do_action('group_loop_start');
@@ -311,54 +311,56 @@ function bp_has_groups( $args = '' ) {
 		$slug = $bp->groups->current_group->slug;
 	}
 
+	// Default search string
+	if ( ! empty( $_REQUEST['group-filter-box'] ) ) {
+		$search_terms = $_REQUEST['group-filter-box'];
+	} elseif ( isset( $_REQUEST['s'] ) && !empty( $_REQUEST['s'] ) ) {
+		$search_terms = $_REQUEST['s'];
+	} else {
+		$search_terms = false;
+	}
+
 	$defaults = array(
-		'type'            => $type, // 'type' is an override for 'order' and 'orderby'. See docblock.
-		'order'           => 'DESC',
-		'orderby'         => 'last_activity',
-		'page'            => 1,
-		'per_page'        => 20,
-		'max'             => false,
-		'show_hidden'     => false,
-
-		'page_arg'        => 'grpage', // See https://buddypress.trac.wordpress.org/ticket/3679
-
-		'user_id'         => $user_id, // Pass a user ID to limit to groups this user has joined
-		'slug'            => $slug,    // Pass a group slug to only return that group
-		'search_terms'    => '',       // Pass search terms to return only matching groups
-		'meta_query'      => false,    // Filter by groupmeta. See WP_Meta_Query for format
-		'include'         => false,    // Pass comma separated list or array of group ID's to return only these groups
-		'exclude'         => false,    // Pass comma separated list or array of group ID's to exclude these groups
-
-		'populate_extras' => true,     // Get extra meta - is_member, is_banned
+		'type'              => $type, // 'type' is an override for 'order' and 'orderby'. See docblock.
+		'order'             => 'DESC',
+		'orderby'           => 'last_activity',
+		'page'              => 1,
+		'per_page'          => 20,
+		'max'               => false,
+		'show_hidden'       => false,
+
+		'page_arg'          => 'grpage', // See https://buddypress.trac.wordpress.org/ticket/3679
+
+		'user_id'           => $user_id, // Pass a user ID to limit to groups this user has joined
+		'slug'              => $slug,    // Pass a group slug to only return that group
+		'search_terms'      => $search_terms, // Pass search terms to return only matching groups
+		'meta_query'        => false,    // Filter by groupmeta. See WP_Meta_Query for format
+		'include'           => false,    // Pass comma separated list or array of group ID's to return only these groups
+		'exclude'           => false,    // Pass comma separated list or array of group ID's to exclude these groups
+
+		'populate_extras'   => true,     // Get extra meta - is_member, is_banned
+		'update_meta_cache' => true,
 	);
 
-	$r = wp_parse_args( $args, $defaults );
-
-	if ( empty( $r['search_terms'] ) ) {
-		if ( isset( $_REQUEST['group-filter-box'] ) && !empty( $_REQUEST['group-filter-box'] ) )
-			$r['search_terms'] = $_REQUEST['group-filter-box'];
-		elseif ( isset( $_REQUEST['s'] ) && !empty( $_REQUEST['s'] ) )
-			$r['search_terms'] = $_REQUEST['s'];
-		else
-			$r['search_terms'] = false;
-	}
+	$r = bp_parse_args( $args, $defaults, 'has_groups' );
 
 	$groups_template = new BP_Groups_Template( array(
-		'type'            => $r['type'],
-		'order'           => $r['order'],
-		'orderby'         => $r['orderby'],
-		'page'            => (int) $r['page'],
-		'per_page'        => (int) $r['per_page'],
-		'max'             => (int) $r['max'],
-		'show_hidden'     => $r['show_hidden'],
-		'page_arg'        => $r['page_arg'],
-		'user_id'         => (int) $r['user_id'],
-		'slug'            => $r['slug'],
-		'search_terms'    => $r['search_terms'],
-		'meta_query'      => $r['meta_query'],
-		'include'         => $r['include'],
-		'exclude'         => $r['exclude'],
-		'populate_extras' => (bool) $r['populate_extras']
+		'type'              => $r['type'],
+		'order'             => $r['order'],
+		'orderby'           => $r['orderby'],
+		'page'              => (int) $r['page'],
+		'per_page'          => (int) $r['per_page'],
+		'max'               => (int) $r['max'],
+		'show_hidden'       => $r['show_hidden'],
+		'page_arg'          => $r['page_arg'],
+		'user_id'           => (int) $r['user_id'],
+		'slug'              => $r['slug'],
+		'search_terms'      => $r['search_terms'],
+		'meta_query'        => $r['meta_query'],
+		'include'           => $r['include'],
+		'exclude'           => $r['exclude'],
+		'populate_extras'   => (bool) $r['populate_extras'],
+		'update_meta_cache' => (bool) $r['update_meta_cache'],
 	) );
 
 	return apply_filters( 'bp_has_groups', $groups_template->has_groups(), $groups_template, $r );
@@ -521,7 +523,7 @@ function bp_group_avatar( $args = '' ) {
 
 		/* Fetch the avatar from the folder, if not provide backwards compat. */
 		if ( !$avatar = bp_core_fetch_avatar( array( 'item_id' => $groups_template->group->id, 'object' => 'group', 'type' => $type, 'avatar_dir' => 'group-avatars', 'alt' => $alt, 'css_id' => $id, 'class' => $class, 'width' => $width, 'height' => $height, 'title' => $groups_template->group->name, 'alt' => $alt ) ) )
-			$avatar = '<img src="' . esc_attr( $groups_template->group->avatar_thumb ) . '" class="avatar" alt="' . esc_attr( $groups_template->group->name ) . '" />';
+			$avatar = '<img src="' . esc_url( $groups_template->group->avatar_thumb ) . '" class="avatar" alt="' . esc_attr( $groups_template->group->name ) . '" />';
 
 		return apply_filters( 'bp_get_group_avatar', $avatar );
 	}
@@ -621,16 +623,30 @@ function bp_group_description_editable( $group = false ) {
 		return apply_filters( 'bp_get_group_description_editable', $group->description );
 	}
 
+/**
+ * Output an excerpt of the group description.
+ *
+ * @param object $group Optional. The group being referenced. Defaults to the
+ *        group currently being iterated on in the groups loop.
+ */
 function bp_group_description_excerpt( $group = false ) {
 	echo bp_get_group_description_excerpt( $group );
 }
+	/**
+	 * Get an excerpt of a group description.
+	 *
+	 * @param object $group Optional. The group being referenced. Defaults
+	 *        to the group currently being iterated on in the groups loop.
+	 * @return string Excerpt.
+	 */
 	function bp_get_group_description_excerpt( $group = false ) {
 		global $groups_template;
 
-		if ( empty( $group ) )
+		if ( empty( $group ) ) {
 			$group =& $groups_template->group;
+		}
 
-		return apply_filters( 'bp_get_group_description_excerpt', bp_create_excerpt( $group->description ) );
+		return apply_filters( 'bp_get_group_description_excerpt', bp_create_excerpt( $group->description ), $group );
 	}
 
 
@@ -760,10 +776,24 @@ function bp_group_is_mod() {
 function bp_group_list_admins( $group = false ) {
 	global $groups_template;
 
-	if ( empty( $group ) )
+	if ( empty( $group ) ) {
 		$group =& $groups_template->group;
+	}
 
-	if ( !empty( $group->admins ) ) { ?>
+	// fetch group admins if 'populate_extras' flag is false
+	if ( empty( $group->args['populate_extras'] ) ) {
+		$query = new BP_Group_Member_Query( array(
+			'group_id'   => $group->id,
+			'group_role' => 'admin',
+			'type'       => 'first_joined',
+		) );
+
+		if ( ! empty( $query->results ) ) {
+			$group->admins = $query->results;
+		}
+	}
+
+	if ( ! empty( $group->admins ) ) { ?>
 		<ul id="group-admins">
 			<?php foreach( (array) $group->admins as $admin ) { ?>
 				<li>
@@ -780,10 +810,24 @@ function bp_group_list_admins( $group = false ) {
 function bp_group_list_mods( $group = false ) {
 	global $groups_template;
 
-	if ( empty( $group ) )
+	if ( empty( $group ) ) {
 		$group =& $groups_template->group;
+	}
 
-	if ( !empty( $group->mods ) ) : ?>
+	// fetch group mods if 'populate_extras' flag is false
+	if ( empty( $group->args['populate_extras'] ) ) {
+		$query = new BP_Group_Member_Query( array(
+			'group_id'   => $group->id,
+			'group_role' => 'mod',
+			'type'       => 'first_joined',
+		) );
+
+		if ( ! empty( $query->results ) ) {
+			$group->mods = $query->results;
+		}
+	}
+
+	if ( ! empty( $group->mods ) ) : ?>
 
 		<ul id="group-mods">
 
@@ -884,14 +928,14 @@ function bp_group_search_form() {
 	$label = __('Filter Groups', 'buddypress');
 	$name = 'group-filter-box';
 
-?>
-	<form action="<?php echo $action ?>" id="group-search-form" method="post">
-		<label for="<?php echo $name ?>" id="<?php echo $name ?>-label"><?php echo $label ?></label>
-		<input type="search" name="<?php echo $name ?>" id="<?php echo $name ?>" value="<?php echo $value ?>"<?php echo $disabled ?> />
+	$search_form_html = '<form action="' . $action . '" id="group-search-form" method="post">
+		<label for="'. $name .'" id="'. $name .'-label">'. $label .'</label>
+		<input type="search" name="'. $name . '" id="'. $name .'" value="'. $value .'"'.  $disabled .' />
 
-		<?php wp_nonce_field( 'group-filter-box', '_wpnonce_group_filter' ) ?>
-	</form>
-<?php
+		'. wp_nonce_field( 'group-filter-box', '_wpnonce_group_filter', true, false ) .'
+		</form>';
+
+	echo apply_filters( 'bp_group_search_form', $search_form_html );
 }
 
 function bp_group_show_no_groups_message() {
@@ -929,7 +973,7 @@ function bp_groups_pagination_count() {
 		$to_num    = bp_core_number_format( ( $start_num + ( $groups_template->pag_num - 1 ) > $groups_template->total_group_count ) ? $groups_template->total_group_count : $start_num + ( $groups_template->pag_num - 1 ) );
 		$total     = bp_core_number_format( $groups_template->total_group_count );
 
-		return apply_filters( 'bp_get_groups_pagination_count', sprintf( __( 'Viewing group %1$s to %2$s (of %3$s groups)', 'buddypress' ), $from_num, $to_num, $total ) );
+		return apply_filters( 'bp_get_groups_pagination_count', sprintf( _n( 'Viewing group %1$s to %2$s (of %3$s group)', 'Viewing group %1$s to %2$s (of %3$s groups)', $total, 'buddypress' ), $from_num, $to_num, $total ), $from_num, $to_num, $total );
 	}
 
 function bp_groups_auto_join() {
@@ -1290,7 +1334,7 @@ function bp_group_mod_memberlist( $admin_list = false, $group = false ) {
 					<?php echo bp_core_get_userlink( $mod->user_id ); ?>
 
 					<span class="small">
-						<a href="<?php bp_group_member_promote_admin_link( array( 'user_id' => $mod->user_id ) ) ?>" class="button confirm mod-promote-to-admin" title="<?php _e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
+						<a href="<?php bp_group_member_promote_admin_link( array( 'user_id' => $mod->user_id ) ) ?>" class="button confirm mod-promote-to-admin" title="<?php esc_attr_e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
 						<a class="button confirm mod-demote-to-member" href="<?php bp_group_member_demote_link($mod->user_id) ?>"><?php _e( 'Demote to Member', 'buddypress' ) ?></a>
 					</span>
 				</h5>
@@ -1780,23 +1824,25 @@ function bp_group_join_button( $group = false ) {
 
 				case 'private' :
 
-					// Member has not requested membership yet
-					if ( !bp_group_has_requested_membership( $group ) ) {
+					// Member has outstanding invitation -
+					// show an "Accept Invitation" button
+					if ( $group->is_invited ) {
 						$button = array(
-							'id'                => 'request_membership',
+							'id'                => 'accept_invite',
 							'component'         => 'groups',
 							'must_be_logged_in' => true,
 							'block_self'        => false,
 							'wrapper_class'     => 'group-button ' . $group->status,
 							'wrapper_id'        => 'groupbutton-' . $group->id,
-							'link_href'         => wp_nonce_url( bp_get_group_permalink( $group ) . 'request-membership', 'groups_request_membership' ),
-							'link_text'         => __( 'Request Membership', 'buddypress' ),
-							'link_title'        => __( 'Request Membership', 'buddypress' ),
-							'link_class'        => 'group-button request-membership',
+							'link_href'         => add_query_arg( 'redirect_to', bp_get_group_permalink( $group ), bp_get_group_accept_invite_link( $group ) ),
+							'link_text'         => __( 'Accept Invitation', 'buddypress' ),
+							'link_title'        => __( 'Accept Invitation', 'buddypress' ),
+							'link_class'        => 'group-button accept-invite',
 						);
 
-					// Member has requested membership already
-					} else {
+					// Member has requested membership but request is pending -
+					// show a "Request Sent" button
+					} elseif ( $group->is_pending ) {
 						$button = array(
 							'id'                => 'membership_requested',
 							'component'         => 'groups',
@@ -1809,6 +1855,22 @@ function bp_group_join_button( $group = false ) {
 							'link_title'        => __( 'Request Sent', 'buddypress' ),
 							'link_class'        => 'group-button pending membership-requested',
 						);
+
+					// Member has not requested membership yet -
+					// show a "Request Membership" button
+					} else {
+						$button = array(
+							'id'                => 'request_membership',
+							'component'         => 'groups',
+							'must_be_logged_in' => true,
+							'block_self'        => false,
+							'wrapper_class'     => 'group-button ' . $group->status,
+							'wrapper_id'        => 'groupbutton-' . $group->id,
+							'link_href'         => wp_nonce_url( bp_get_group_permalink( $group ) . 'request-membership', 'groups_request_membership' ),
+							'link_text'         => __( 'Request Membership', 'buddypress' ),
+							'link_title'        => __( 'Request Membership', 'buddypress' ),
+							'link_class'        => 'group-button request-membership',
+						);
 					}
 
 					break;
@@ -1819,6 +1881,43 @@ function bp_group_join_button( $group = false ) {
 		return bp_get_button( apply_filters( 'bp_get_group_join_button', $button ) );
 	}
 
+/**
+ * Output the Create a Group button.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_group_create_button() {
+	echo bp_get_group_create_button();
+}
+	/**
+	 * Get the Create a Group button.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @return string
+	 */
+	function bp_get_group_create_button() {
+		if ( ! is_user_logged_in() ) {
+			return false;
+		}
+
+		if ( ! bp_user_can_create_groups() ) {
+			return false;
+		}
+
+		$button_args = array(
+			'id'         => 'create_group',
+			'component'  => 'groups',
+			'link_text'  => __( 'Create a Group', 'buddypress' ),
+			'link_title' => __( 'Create a Group', 'buddypress' ),
+			'link_class' => 'button group-create bp-title-button',
+			'link_href'  => trailingslashit( bp_get_root_domain() ) . trailingslashit( bp_get_groups_root_slug() ) . trailingslashit( 'create' ),
+			'wrapper'    => false,
+		);
+
+		return bp_get_button( apply_filters( 'bp_get_group_create_button', $button_args ) );
+	}
+
 /**
  * Prints a message if the group is not visible to the current user (it is a
  * hidden or private group, and the user does not have access).
@@ -1878,6 +1977,7 @@ function bp_total_group_count_for_user( $user_id = 0 ) {
 	function bp_get_total_group_count_for_user( $user_id = 0 ) {
 		return apply_filters( 'bp_get_total_group_count_for_user', groups_total_groups_for_user( $user_id ), $user_id );
 	}
+	add_filter( 'bp_get_total_group_count_for_user', 'bp_core_number_format' );
 
 
 /***************************************************************************
@@ -1897,11 +1997,86 @@ class BP_Groups_Group_Members_Template {
 	var $pag_links;
 	var $total_group_count;
 
-	function __construct( $group_id, $per_page, $max, $exclude_admins_mods, $exclude_banned, $exclude, $group_role = false ) {
+	/**
+	 * Constructor.
+	 *
+	 * @param array $args {
+	 *     An array of optional arguments.
+	 *     @type int $group_id ID of the group whose members are being
+	 *	     queried. Default: current group ID.
+	 *     @type int $page Page of results to be queried. Default: 1.
+	 *     @type int $per_page Number of items to return per page of
+	 *           results. Default: 20.
+	 *     @type int $max Optional. Max number of items to return.
+	 *     @type array $exclude Optional. Array of user IDs to exclude.
+	 *     @type bool|int True (or 1) to exclude admins and mods from
+	 *           results. Default: 1.
+	 *     @type bool|int True (or 1) to exclude banned users from results.
+	 *           Default: 1.
+	 *     @type array $group_role Optional. Array of group roles to include.
+	 *     @type string $search_terms Optional. Search terms to match.
+	 * }
+	 */
+	function __construct( $args = array() ) {
 
-		$this->pag_page = isset( $_REQUEST['mlpage'] ) ? intval( $_REQUEST['mlpage'] ) : 1;
+		// Backward compatibility with old method of passing arguments
+		if ( ! is_array( $args ) || func_num_args() > 1 ) {
+			_deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
+
+			$old_args_keys = array(
+				0 => 'group_id',
+				1 => 'per_page',
+				2 => 'max',
+				3 => 'exclude_admins_mods',
+				4 => 'exclude_banned',
+				5 => 'exclude',
+				6 => 'group_role',
+			);
+
+			$func_args = func_get_args();
+			$args      = bp_core_parse_args_array( $old_args_keys, $func_args );
+		}
+
+		$r = wp_parse_args( $args, array(
+			'group_id'            => bp_get_current_group_id(),
+			'page'                => 1,
+			'per_page'            => 20,
+			'max'                 => false,
+			'exclude'             => false,
+			'exclude_admins_mods' => 1,
+			'exclude_banned'      => 1,
+			'group_role'          => false,
+			'search_terms'        => false,
+			'type'                => 'last_joined',
+		) );
+
+		// @todo No
+		extract( $r );
+
+		$this->pag_page = isset( $_REQUEST['mlpage'] ) ? intval( $_REQUEST['mlpage'] ) : $r['page'];
 		$this->pag_num  = isset( $_REQUEST['num'] ) ? intval( $_REQUEST['num'] ) : $per_page;
-		$this->members  = groups_get_group_members( $group_id, $this->pag_num, $this->pag_page, $exclude_admins_mods, $exclude_banned, $exclude, $group_role );
+
+		/**
+		 * Check the current group is the same as the supplied group ID.
+		 * It can differ when using {@link bp_group_has_members()} outside the Groups screens.
+		 */
+		$current_group = groups_get_current_group();
+		if ( ! $current_group || $current_group && $current_group->id !== bp_get_current_group_id() ) {
+			$current_group = groups_get_group( array( 'group_id' => $r['group_id'] ) );
+		}
+
+		// Assemble the base URL for pagination
+		$base_url = trailingslashit( bp_get_group_permalink( $current_group ) . bp_current_action() );
+		if ( bp_action_variable() ) {
+			$base_url = trailingslashit( $base_url . bp_action_variable() );
+		}
+
+		$members_args = $r;
+
+		$members_args['page']     = $this->pag_page;
+		$members_args['per_page'] = $this->pag_num;
+
+		$this->members = groups_get_group_members( $members_args );
 
 		if ( !$max || $max >= (int) $this->members['count'] )
 			$this->total_member_count = (int) $this->members['count'];
@@ -1920,7 +2095,7 @@ class BP_Groups_Group_Members_Template {
 		}
 
 		$this->pag_links = paginate_links( array(
-			'base' => add_query_arg( 'mlpage', '%#%' ),
+			'base' => add_query_arg( array( 'mlpage' => '%#%' ), $base_url ),
 			'format' => '',
 			'total' => !empty( $this->pag_num ) ? ceil( $this->total_member_count / $this->pag_num ) : $this->total_member_count,
 			'current' => $this->pag_page,
@@ -1974,20 +2149,55 @@ class BP_Groups_Group_Members_Template {
 	}
 }
 
+/**
+ * Initialize a group member query loop.
+ *
+ * @param array $args {
+ *     An array of optional arguments.
+ *     @type int $group_id ID of the group whose members are being queried.
+ *           Default: current group ID.
+ *     @type int $page Page of results to be queried. Default: 1.
+ *     @type int $per_page Number of items to return per page of results.
+ *           Default: 20.
+ *     @type int $max Optional. Max number of items to return.
+ *     @type array $exclude Optional. Array of user IDs to exclude.
+ *     @type bool|int True (or 1) to exclude admins and mods from results.
+ *           Default: 1.
+ *     @type bool|int True (or 1) to exclude banned users from results.
+ *           Default: 1.
+ *     @type array $group_role Optional. Array of group roles to include.
+ *     @type string $type Optional. Sort order of results. 'last_joined',
+ *           'first_joined', or any of the $type params available in
+ *           {@link BP_User_Query}. Default: 'last_joined'.
+ *     @type string $search_terms Optional. Search terms to match.
+ * }
+ */
 function bp_group_has_members( $args = '' ) {
 	global $members_template;
 
+	$exclude_admins_mods = 1;
+
+	if ( bp_is_group_members() ) {
+		$exclude_admins_mods = 0;
+	}
+
 	$r = wp_parse_args( $args, array(
-		'group_id' => bp_get_current_group_id(),
-		'per_page' => 20,
-		'max' => false,
-		'exclude' => false,
-		'exclude_admins_mods' => 1,
-		'exclude_banned' => 1,
-		'group_role' => false,
+		'group_id'            => bp_get_current_group_id(),
+		'page'                => 1,
+		'per_page'            => 20,
+		'max'                 => false,
+		'exclude'             => false,
+		'exclude_admins_mods' => $exclude_admins_mods,
+		'exclude_banned'      => 1,
+		'group_role'          => false,
+		'search_terms'        => false,
+		'type'                => 'last_joined',
 	) );
 
-	$members_template = new BP_Groups_Group_Members_Template( $r['group_id'], $r['per_page'], $r['max'], (int) $r['exclude_admins_mods'], (int) $r['exclude_banned'], $r['exclude'], $r['group_role'] );
+	if ( empty( $r['search_terms'] ) && ! empty( $_REQUEST['s'] ) )
+		$r['search_terms'] = $_REQUEST['s'];
+
+	$members_template = new BP_Groups_Group_Members_Template( $r );
 	return apply_filters( 'bp_group_has_members', $members_template->has_members(), $members_template );
 }
 
@@ -2150,7 +2360,7 @@ function bp_group_member_pagination_count() {
 		$to_num = bp_core_number_format( ( $start_num + ( $members_template->pag_num - 1 ) > $members_template->total_member_count ) ? $members_template->total_member_count : $start_num + ( $members_template->pag_num - 1 ) );
 		$total = bp_core_number_format( $members_template->total_member_count );
 
-		return apply_filters( 'bp_get_group_member_pagination_count', sprintf( __( 'Viewing members %1$s to %2$s (of %3$s members)', 'buddypress' ), $from_num, $to_num, $total ) );
+		return apply_filters( 'bp_get_group_member_pagination_count', sprintf( _n( 'Viewing member %1$s to %2$s (of %3$s member)', 'Viewing members %1$s to %2$s (of %3$s members)', $total, 'buddypress' ), $from_num, $to_num, $total ), $from_num, $to_num, $total );
 	}
 
 function bp_group_member_admin_pagination() {
@@ -2163,6 +2373,57 @@ function bp_group_member_admin_pagination() {
 		return $members_template->pag_links;
 	}
 
+/**
+ * Output the Group members template
+ *
+ * @since BuddyPress (?)
+ *
+ * @return string html output
+ */
+function bp_groups_members_template_part() {
+	?>
+	<div class="item-list-tabs" id="subnav" role="navigation">
+		<ul>
+			<li class="groups-members-search" role="search">
+				<?php bp_directory_members_search_form(); ?>
+			</li>
+
+			<?php bp_groups_members_filter(); ?>
+			<?php do_action( 'bp_members_directory_member_sub_types' ); ?>
+
+		</ul>
+	</div>
+
+	<div id="members-group-list" class="group_members dir-list">
+
+		<?php bp_get_template_part( 'groups/single/members' ); ?>
+
+	</div>
+	<?php
+}
+
+/**
+ * Output the Group members filters
+ *
+ * @since BuddyPress (?)
+ *
+ * @return string html output
+ */
+function bp_groups_members_filter() {
+	?>
+	<li id="group_members-order-select" class="last filter">
+		<label for="group_members-order-by"><?php _e( 'Order By:', 'buddypress' ); ?></label>
+		<select id="group_members-order-by">
+			<option value="last_joined"><?php _e( 'Newest', 'buddypress' ); ?></option>
+			<option value="first_joined"><?php _e( 'Oldest', 'buddypress' ); ?></option>
+			<option value="alphabetical"><?php _e( 'Alphabetical', 'buddypress' ); ?></option>
+
+			<?php do_action( 'bp_groups_members_order_options' ); ?>
+
+		</select>
+	</li>
+	<?php
+}
 
 /***************************************************************************
  * Group Creation Process Template Tags
@@ -2204,8 +2465,10 @@ function bp_group_creation_tabs() {
 	if ( !is_array( $bp->groups->group_creation_steps ) )
 		return false;
 
-	if ( !bp_get_groups_current_create_step() )
-		$bp->groups->current_create_step = array_shift( array_keys( $bp->groups->group_creation_steps ) );
+	if ( !bp_get_groups_current_create_step() ) {
+		$keys = array_keys( $bp->groups->group_creation_steps );
+		$bp->groups->current_create_step = array_shift( $keys );
+	}
 
 	$counter = 1;
 
@@ -2233,8 +2496,10 @@ function bp_group_creation_form_action() {
 	function bp_get_group_creation_form_action() {
 		global $bp;
 
-		if ( !bp_action_variable( 1 ) )
-			$bp->action_variables[1] = array_shift( array_keys( $bp->groups->group_creation_steps ) );
+		if ( !bp_action_variable( 1 ) ) {
+			$keys = array_keys( $bp->groups->group_creation_steps );
+			$bp->action_variables[1] = array_shift( $keys );
+		}
 
 		return apply_filters( 'bp_get_group_creation_form_action', trailingslashit( bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create/step/' . bp_action_variable( 1 ) ) );
 	}
@@ -2247,7 +2512,8 @@ function bp_is_group_creation_step( $step_slug ) {
 		return false;
 
 	/* If this the first step, we can just accept and return true */
-	if ( !bp_action_variable( 1 ) && array_shift( array_keys( $bp->groups->group_creation_steps ) ) == $step_slug )
+	$keys = array_keys( $bp->groups->group_creation_steps );
+	if ( !bp_action_variable( 1 ) && array_shift( $keys ) == $step_slug )
 		return true;
 
 	/* Before allowing a user to see a group creation step we must make sure previous steps are completed */
@@ -2289,7 +2555,8 @@ function bp_are_previous_group_creation_steps_complete( $step_slug ) {
 	global $bp;
 
 	/* If this is the first group creation step, return true */
-	if ( array_shift( array_keys( $bp->groups->group_creation_steps ) ) == $step_slug )
+	$keys = array_keys( $bp->groups->group_creation_steps );
+	if ( array_shift( $keys ) == $step_slug )
 		return true;
 
 	reset( $bp->groups->group_creation_steps );
@@ -2433,7 +2700,8 @@ function bp_groups_current_create_step() {
 function bp_is_last_group_creation_step() {
 	global $bp;
 
-	$last_step = array_pop( array_keys( $bp->groups->group_creation_steps ) );
+	$keys      = array_keys( $bp->groups->group_creation_steps );
+	$last_step = array_pop( $keys );
 
 	if ( $last_step == bp_get_groups_current_create_step() )
 		return true;
@@ -2444,7 +2712,8 @@ function bp_is_last_group_creation_step() {
 function bp_is_first_group_creation_step() {
 	global $bp;
 
-	$first_step = array_shift( array_keys( $bp->groups->group_creation_steps ) );
+	$keys       = array_keys( $bp->groups->group_creation_steps );
+	$first_step = array_shift( $keys );
 
 	if ( $first_step == bp_get_groups_current_create_step() )
 		return true;
@@ -2496,14 +2765,15 @@ function bp_new_group_invite_friend_list() {
 function bp_directory_groups_search_form() {
 
 	$default_search_value = bp_get_search_default_text( 'groups' );
-	$search_value         = !empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : $default_search_value; ?>
+	$search_value         = !empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : $default_search_value;
 
-	<form action="" method="get" id="search-groups-form">
-		<label><input type="text" name="s" id="groups_search" placeholder="<?php echo esc_attr( $search_value ) ?>" /></label>
-		<input type="submit" id="groups_search_submit" name="groups_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
-	</form>
+	$search_form_html = '<form action="" method="get" id="search-groups-form">
+		<label><input type="text" name="s" id="groups_search" placeholder="'. esc_attr( $search_value ) .'" /></label>
+		<input type="submit" id="groups_search_submit" name="groups_search_submit" value="'. __( 'Search', 'buddypress' ) .'" />
+	</form>';
+
+	echo apply_filters( 'bp_directory_groups_search_form', $search_form_html );
 
-<?php
 }
 
 /**
@@ -2598,25 +2868,60 @@ function bp_group_current_admin_tab() {
  * Group Avatar Template Tags
  **/
 
-function bp_group_current_avatar() {
-	global $bp;
-
-	if ( $bp->groups->current_group->avatar_full ) { ?>
+/**
+ * Outputs the current group avatar
+ *
+ * @since BuddyPress (1.0)
+ * @param string $type thumb or full ?
+ * @uses bp_get_group_current_avatar() to get the avatar of the current group
+ */
+function bp_group_current_avatar( $type = 'thumb' ) {
+	echo bp_get_group_current_avatar( $type );
+}
+	/**
+	 * Returns the current group avatar
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param string $type thumb or full ?
+	 * @return string $tab The current tab's slug.
+	 */
+	function bp_get_group_current_avatar( $type = 'thumb' ) {
+
+		$group_avatar = bp_core_fetch_avatar( array(
+			'item_id'    => bp_get_current_group_id(),
+			'object'     => 'group',
+			'type'       => $type,
+			'avatar_dir' => 'group-avatars',
+			'alt'        => __( 'Group avatar', 'buddypress' ),
+			'class'      => 'avatar'
+		) );
 
-		<img src="<?php echo esc_attr( $bp->groups->current_group->avatar_full ) ?>" alt="<?php _e( 'Group Avatar', 'buddypress' ) ?>" class="avatar" />
+		return apply_filters( 'bp_get_group_current_avatar', $group_avatar );
+	}
 
-	<?php } else { ?>
+function bp_get_group_has_avatar( $group_id = false ) {
+	global $bp;
 
-		<img src="<?php echo $bp->groups->image_base . '/none.gif' ?>" alt="<?php _e( 'No Group Avatar', 'buddypress' ) ?>" class="avatar" />
+	if ( false === $group_id ) {
+		$group_id = bp_get_current_group_id();
+	}
 
-	<?php }
-}
+	// Todo - this looks like an overgeneral check
+	if ( ! empty( $_FILES ) ) {
+		return false;
+	}
 
-function bp_get_group_has_avatar() {
-	global $bp;
+	$group_avatar = bp_core_fetch_avatar( array(
+		'item_id' => $group_id,
+		'object' => 'group',
+		'no_grav' => true,
+		'html' => false,
+	) );
 
-	if ( !empty( $_FILES ) || !bp_core_fetch_avatar( array( 'item_id' => $bp->groups->current_group->id, 'object' => 'group', 'no_grav' => true ) ) )
+	if ( bp_core_avatar_default( 'local' ) === $group_avatar ) {
 		return false;
+	}
 
 	return true;
 }
@@ -2668,24 +2973,81 @@ class BP_Groups_Membership_Requests_Template {
 	var $pag_links;
 	var $total_request_count;
 
-	function __construct( $group_id, $per_page, $max ) {
+	/**
+	 * Constructor method.
+	 *
+	 * @param array $args {
+	 *     @type int $group_id ID of the group whose membership requests
+	 *           are being queried. Default: current group id.
+	 *     @type int $per_page Number of records to return per page of
+	 *           results. Default: 10.
+	 *     @type int $page Page of results to show. Default: 1.
+	 *     @type int $max Max items to return. Default: false (show all)
+	 * }
+	 */
+	function __construct( $args = array() ) {
+
+		// Backward compatibility with old method of passing arguments
+		if ( ! is_array( $args ) || func_num_args() > 1 ) {
+			_deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
 
-		$this->pag_page = isset( $_REQUEST['mrpage'] ) ? intval( $_REQUEST['mrpage'] ) : 1;
-		$this->pag_num  = isset( $_REQUEST['num'] ) ? intval( $_REQUEST['num'] ) : $per_page;
-		$this->requests = BP_Groups_Group::get_membership_requests( $group_id, $this->pag_num, $this->pag_page );
+			$old_args_keys = array(
+				0 => 'group_id',
+				1 => 'per_page',
+				2 => 'max',
+			);
 
-		if ( !$max || $max >= (int) $this->requests['total'] )
-			$this->total_request_count = (int) $this->requests['total'];
-		else
-			$this->total_request_count = (int) $max;
+			$func_args = func_get_args();
+			$args      = bp_core_parse_args_array( $old_args_keys, $func_args );
+		}
 
-		$this->requests = $this->requests['requests'];
+		$r = wp_parse_args( $args, array(
+			'group_id' => bp_get_current_group_id(),
+			'per_page' => 10,
+			'page'     => 1,
+			'max'      => false,
+			'type'     => 'first_joined',
+		) );
 
-		if ( $max ) {
-			if ( $max >= count($this->requests) )
+		$this->pag_page = isset( $_REQUEST['mrpage'] ) ? intval( $_REQUEST['mrpage'] ) : $r['page'];
+		$this->pag_num  = isset( $_REQUEST['num'] ) ? intval( $_REQUEST['num'] ) : $r['per_page'];
+
+		$mquery = new BP_Group_Member_Query( array(
+			'group_id' => $r['group_id'],
+			'type'     => $r['type'],
+			'per_page' => $this->pag_num,
+			'page'     => $this->pag_page,
+
+			// These filters ensure we only get pending requests
+			'is_confirmed' => false,
+			'inviter_id'   => 0,
+		) );
+
+		$this->requests      = array_values( $mquery->results );
+		$this->request_count = count( $this->requests );
+
+		// Compatibility with legacy format of request data objects
+		foreach ( $this->requests as $rk => $rv ) {
+			// For legacy reasons, the 'id' property of each
+			// request must match the membership id, not the ID of
+			// the user (as it's returned by BP_Group_Member_Query)
+			$this->requests[ $rk ]->user_id = $rv->ID;
+			$this->requests[ $rk ]->id      = $rv->membership_id;
+
+			// Miscellaneous values
+			$this->requests[ $rk ]->group_id   = $r['group_id'];
+		}
+
+		if ( !$r['max'] || $r['max'] >= (int) $mquery->total_users )
+			$this->total_request_count = (int) $mquery->total_users;
+		else
+			$this->total_request_count = (int) $r['max'];
+
+		if ( $r['max'] ) {
+			if ( $r['max'] >= count($this->requests) )
 				$this->request_count = count($this->requests);
 			else
-				$this->request_count = (int) $max;
+				$this->request_count = (int) $r['max'];
 		} else {
 			$this->request_count = count($this->requests);
 		}
@@ -2744,19 +3106,30 @@ class BP_Groups_Membership_Requests_Template {
 	}
 }
 
+/**
+ * Initialize a group membership request template loop.
+ *
+ * @param array $args {
+ *     @type int $group_id ID of the group. Defaults to current group.
+ *     @type int $per_page Number of records to return per page. Default: 10.
+ *     @type int $page Page of results to return. Default: 1.
+ *     @type int $max Max number of items to return. Default: false.
+ * }
+ * @return bool True if there are requests, otherwise false.
+ */
 function bp_group_has_membership_requests( $args = '' ) {
-	global $requests_template, $groups_template;
+	global $requests_template;
 
 	$defaults = array(
-		'group_id' => $groups_template->group->id,
+		'group_id' => bp_get_current_group_id(),
 		'per_page' => 10,
+		'page'     => 1,
 		'max'      => false
 	);
 
 	$r = wp_parse_args( $args, $defaults );
-	extract( $r, EXTR_SKIP );
 
-	$requests_template = new BP_Groups_Membership_Requests_Template( $group_id, $per_page, $max );
+	$requests_template = new BP_Groups_Membership_Requests_Template( $r );
 	return apply_filters( 'bp_group_has_membership_requests', $requests_template->has_requests(), $requests_template );
 }
 
@@ -2782,18 +3155,18 @@ function bp_group_request_reject_link() {
 	echo bp_get_group_request_reject_link();
 }
 	function bp_get_group_request_reject_link() {
-		global $requests_template, $groups_template;
+		global $requests_template;
 
-		return apply_filters( 'bp_get_group_request_reject_link', wp_nonce_url( bp_get_group_permalink( $groups_template->group ) . 'admin/membership-requests/reject/' . $requests_template->request->id, 'groups_reject_membership_request' ) );
+		return apply_filters( 'bp_get_group_request_reject_link', wp_nonce_url( bp_get_group_permalink( groups_get_current_group() ) . 'admin/membership-requests/reject/' . $requests_template->request->membership_id, 'groups_reject_membership_request' ) );
 	}
 
 function bp_group_request_accept_link() {
 	echo bp_get_group_request_accept_link();
 }
 	function bp_get_group_request_accept_link() {
-		global $requests_template, $groups_template;
+		global $requests_template;
 
-		return apply_filters( 'bp_get_group_request_accept_link', wp_nonce_url( bp_get_group_permalink( $groups_template->group ) . 'admin/membership-requests/accept/' . $requests_template->request->id, 'groups_accept_membership_request' ) );
+		return apply_filters( 'bp_get_group_request_accept_link', wp_nonce_url( bp_get_group_permalink( groups_get_current_group() ) . 'admin/membership-requests/accept/' . $requests_template->request->membership_id, 'groups_accept_membership_request' ) );
 	}
 
 function bp_group_request_user_link() {
@@ -2817,6 +3190,52 @@ function bp_group_request_comment() {
 	echo apply_filters( 'bp_group_request_comment', strip_tags( stripslashes( $requests_template->request->comments ) ) );
 }
 
+/**
+ * Output pagination links for group membership requests.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_group_requests_pagination_links() {
+	echo bp_get_group_requests_pagination_links();
+}
+	/**
+	 * Get pagination links for group membership requests.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @return string
+	 */
+	function bp_get_group_requests_pagination_links() {
+		global $requests_template;
+		return apply_filters( 'bp_get_group_requests_pagination_links', $requests_template->pag_links );
+	}
+
+/**
+ * Output pagination count text for group membership requests.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_group_requests_pagination_count() {
+	echo bp_get_group_requests_pagination_count();
+}
+	/**
+	 * Get pagination count text for group membership requests.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @return string
+	 */
+	function bp_get_group_requests_pagination_count() {
+		global $requests_template;
+
+		$start_num = intval( ( $requests_template->pag_page - 1 ) * $requests_template->pag_num ) + 1;
+		$from_num  = bp_core_number_format( $start_num );
+		$to_num    = bp_core_number_format( ( $start_num + ( $requests_template->pag_num - 1 ) > $requests_template->total_request_count ) ? $requests_template->total_request_count : $start_num + ( $requests_template->pag_num - 1 ) );
+		$total     = bp_core_number_format( $requests_template->total_request_count );
+
+		return apply_filters( 'bp_get_group_requests_pagination_count', sprintf( _n( 'Viewing requests %1$s to %2$s (of %3$s request)', 'Viewing request %1$s to %2$s (of %3$s requests)', $total, 'buddypress' ), $from_num, $to_num, $total ), $from_num, $to_num, $total );
+	}
+
 /************************************************************************************
  * Invite Friends Template Tags
  **/
@@ -2834,9 +3253,62 @@ class BP_Groups_Invite_Template {
 	var $pag_links;
 	var $total_invite_count;
 
-	function __construct( $user_id, $group_id ) {
-		$this->invites      = groups_get_invites_for_group( $user_id, $group_id );
-		$this->invite_count = count( $this->invites );
+	public function __construct( $args = array() ) {
+
+		// Backward compatibility with old method of passing arguments
+		if ( ! is_array( $args ) || func_num_args() > 1 ) {
+			_deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
+
+			$old_args_keys = array(
+				0  => 'user_id',
+				1  => 'group_id',
+			);
+
+			$func_args = func_get_args();
+			$args      = bp_core_parse_args_array( $old_args_keys, $func_args );
+		}
+
+		$r = wp_parse_args( $args, array(
+			'user_id'  => bp_loggedin_user_id(),
+			'group_id' => bp_get_current_group_id(),
+			'page'     => 1,
+			'per_page' => 10,
+		) );
+
+		$this->pag_num  = intval( $r['per_page'] );
+		$this->pag_page = isset( $_REQUEST['invitepage'] ) ? intval( $_REQUEST['invitepage'] ) : $r['page'];
+
+		$iquery = new BP_Group_Member_Query( array(
+			'group_id' => $r['group_id'],
+			'type'     => 'first_joined',
+			'per_page' => $this->pag_num,
+			'page'     => $this->pag_page,
+
+			// These filters ensure we get only pending invites
+			'is_confirmed' => false,
+			'inviter_id'   => $r['user_id'],
+		) );
+		$this->invite_data = $iquery->results;
+
+		$this->total_invite_count = $iquery->total_users;
+		$this->invites		  = array_values( wp_list_pluck( $this->invite_data, 'ID' ) );
+		$this->invite_count       = count( $this->invites );
+
+		// If per_page is set to 0 (show all results), don't generate
+		// pag_links
+		if ( ! empty( $this->pag_num ) ) {
+			$this->pag_links = paginate_links( array(
+				'base'      => add_query_arg( 'invitepage', '%#%' ),
+				'format'    => '',
+				'total'     => ceil( $this->total_invite_count / $this->pag_num ),
+				'current'   => $this->pag_page,
+				'prev_text' => '&larr;',
+				'next_text' => '&rarr;',
+				'mid_size'  => 1,
+			) );
+		} else {
+			$this->pag_links = '';
+		}
 	}
 
 	function has_invites() {
@@ -2874,11 +3346,42 @@ class BP_Groups_Invite_Template {
 
 	function the_invite() {
 		global $group_id;
-
 		$this->in_the_loop      = true;
 		$user_id                = $this->next_invite();
+
 		$this->invite           = new stdClass;
-		$this->invite->user     = new BP_Core_User( $user_id );
+		$this->invite->user     = $this->invite_data[ $user_id ];
+
+		// This method previously populated the user object with
+		// BP_Core_User. We manually configure BP_Core_User data for
+		// backward compatibility.
+		if ( bp_is_active( 'xprofile' ) ) {
+			$this->invite->user->profile_data = BP_XProfile_ProfileData::get_all_for_user( $user_id );
+		}
+
+		$this->invite->user->avatar       = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'full', 'alt' => sprintf( __( 'Avatar of %s', 'buddypress' ), $this->invite->user->fullname ) ) );
+		$this->invite->user->avatar_thumb = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Avatar of %s', 'buddypress' ), $this->invite->user->fullname ) ) );
+		$this->invite->user->avatar_mini  = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Avatar of %s', 'buddypress' ), $this->invite->user->fullname ), 'width' => 30, 'height' => 30 ) );
+		$this->invite->user->email        = $this->invite->user->user_email;
+		$this->invite->user->user_url     = bp_core_get_user_domain( $user_id, $this->invite->user->user_nicename, $this->invite->user->user_login );
+		$this->invite->user->user_link    = "<a href='{$this->invite->user->user_url}' title='{$this->invite->user->fullname}'>{$this->invite->user->fullname}</a>";
+		$this->invite->user->last_active  = bp_core_get_last_activity( $this->invite->user->last_activity, __( 'active %s', 'buddypress' ) );
+
+		if ( bp_is_active( 'groups' ) ) {
+			$total_groups = BP_Groups_Member::total_group_count( $user_id );
+			$this->invite->user->total_groups = sprintf( _n( '%d group', '%d groups', $total_groups, 'buddypress' ), $total_groups );
+		}
+
+		if ( bp_is_active( 'friends' ) ) {
+			$this->invite->user->total_friends = BP_Friends_Friendship::total_friend_count( $user_id );
+		}
+
+		if ( bp_is_active( 'friends' ) ) {
+			$this->invite->user->total_friends = BP_Friends_Friendship::total_friend_count( $user_id );
+		}
+
+		$this->invite->user->total_blogs = null;
+
 		$this->invite->group_id = $group_id; // Globaled in bp_group_has_invites()
 
 		if ( 0 == $this->current_invite ) // loop has just started
@@ -2887,29 +3390,33 @@ class BP_Groups_Invite_Template {
 }
 
 function bp_group_has_invites( $args = '' ) {
-	global $bp, $invites_template, $group_id;
+	global $invites_template, $group_id;
 
-	$defaults = array(
+	$r = wp_parse_args( $args, array(
 		'group_id' => false,
-		'user_id' => bp_loggedin_user_id()
-	);
-
-	$r = wp_parse_args( $args, $defaults );
-	extract( $r, EXTR_SKIP );
+		'user_id'  => bp_loggedin_user_id(),
+		'per_page' => false,
+		'page'     => 1,
+	) );
 
-	if ( !$group_id ) {
-		// Backwards compatibility
-		if ( !empty( $bp->groups->current_group ) )
-			$group_id = $bp->groups->current_group->id;
+	if ( empty( $r['group_id'] ) ) {
+		if ( ! empty( buddypress()->groups->current_group ) ) {
+			$r['group_id'] = bp_get_current_group_id();
+		} else if ( ! empty( buddypress()->groups->new_group_id ) ) {
+			$r['group_id'] = buddypress()->groups->new_group_id;
+		}
+	}
 
-		if ( !empty( $bp->groups->new_group_id ) )
-			$group_id = $bp->groups->new_group_id;
+	// Set the global (for use in BP_Groups_Invite_Template::the_invite())
+	if ( empty( $group_id ) ) {
+		$group_id = $r['group_id'];
 	}
 
-	if ( !$group_id )
+	if ( ! $group_id ) {
 		return false;
+	}
 
-	$invites_template = new BP_Groups_Invite_Template( $user_id, $group_id );
+	$invites_template = new BP_Groups_Invite_Template( $r );
 	return apply_filters( 'bp_group_has_invites', $invites_template->has_invites(), $invites_template );
 }
 
@@ -2967,7 +3474,61 @@ function bp_group_invite_user_remove_invite_url() {
 	function bp_get_group_invite_user_remove_invite_url() {
 		global $invites_template;
 
-		return wp_nonce_url( site_url( bp_get_groups_slug() . '/' . $invites_template->invite->group_id . '/invites/remove/' . $invites_template->invite->user->id ), 'groups_invite_uninvite_user' );
+		$user_id = intval( $invites_template->invite->user->id );
+
+		if ( bp_is_current_action( 'create' ) ) {
+			$uninvite_url = bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create/step/group-invites/?user_id=' . $user_id;
+		} else {
+			$uninvite_url = bp_get_group_permalink( groups_get_current_group() ) . 'send-invites/remove/' . $user_id;
+		}
+
+		return wp_nonce_url( $uninvite_url, 'groups_invite_uninvite_user' );
+	}
+
+/**
+ * Output pagination links for group invitations.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_group_invite_pagination_links() {
+	echo bp_get_group_invite_pagination_links();
+}
+	/**
+	 * Get pagination links for group invitations.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @return string
+	 */
+	function bp_get_group_invite_pagination_links() {
+		global $invites_template;
+		return apply_filters( 'bp_get_group_invite_pagination_links', $invites_template->pag_links );
+	}
+
+/**
+ * Output pagination count text for group invitations.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_group_invite_pagination_count() {
+	echo bp_get_group_invite_pagination_count();
+}
+	/**
+	 * Get pagination count text for group invitations.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @return string
+	 */
+	function bp_get_group_invite_pagination_count() {
+		global $invites_template;
+
+		$start_num = intval( ( $invites_template->pag_page - 1 ) * $invites_template->pag_num ) + 1;
+		$from_num  = bp_core_number_format( $start_num );
+		$to_num    = bp_core_number_format( ( $start_num + ( $invites_template->pag_num - 1 ) > $invites_template->total_invite_count ) ? $invites_template->total_invite_count : $start_num + ( $invites_template->pag_num - 1 ) );
+		$total     = bp_core_number_format( $invites_template->total_invite_count );
+
+		return apply_filters( 'bp_get_groups_pagination_count', sprintf( _n( 'Viewing invitation %1$s to %2$s (of %3$s invitation)', 'Viewing invitation %1$s to %2$s (of %3$s invitations)', $total, 'buddypress' ), $from_num, $to_num, $total ), $from_num, $to_num, $total );
 	}
 
 /***
@@ -3107,3 +3668,57 @@ function bp_groups_action_link( $action = '', $query_args = '', $nonce = false )
 		if ( !empty( $url ) )
 			return $url;
 	}
+
+/** Stats **********************************************************************/
+
+/**
+ * Display the number of groups in user's profile.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $args before|after|user_id
+ * @uses bp_groups_get_profile_stats() to get the stats
+ */
+function bp_groups_profile_stats( $args = '' ) {
+	echo bp_groups_get_profile_stats( $args );
+}
+add_action( 'bp_members_admin_user_stats', 'bp_groups_profile_stats', 8, 1 );
+
+/**
+ * Return the number of groups in user's profile.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $args before|after|user_id
+ * @return string HTML for stats output.
+ */
+function bp_groups_get_profile_stats( $args = '' ) {
+
+	// Parse the args
+	$r = bp_parse_args( $args, array(
+		'before'  => '<li class="bp-groups-profile-stats">',
+		'after'   => '</li>',
+		'user_id' => bp_displayed_user_id(),
+		'groups'  => 0,
+		'output'  => ''
+	), 'groups_get_profile_stats' );
+
+	// Allow completely overloaded output
+	if ( empty( $r['output'] ) ) {
+
+		// Only proceed if a user ID was passed
+		if ( ! empty( $r['user_id'] ) ) {
+
+			// Get the user groups
+			if ( empty( $r['groups'] ) ) {
+				$r['groups'] = absint( bp_get_total_group_count_for_user( $r['user_id'] ) );
+			}
+
+			// If groups exist, show some formatted output
+			$r['output'] = $r['before'] . sprintf( _n( '%s group', '%s groups', $r['groups'], 'buddypress' ), '<strong>' . $r['groups'] . '</strong>' ) . $r['after'];
+		}
+	}
+
+	// Filter and return
+	return apply_filters( 'bp_groups_get_profile_stats', $r['output'], $r );
+}
diff --git a/wp-content/plugins/buddypress/bp-groups/bp-groups-widgets.php b/wp-content/plugins/buddypress/bp-groups/bp-groups-widgets.php
index 7b40d0b556030d3ccc155931410c11f4a8077b4c..43df1e02a815bfda1ccf8a9e077801259f8ef32a 100644
--- a/wp-content/plugins/buddypress/bp-groups/bp-groups-widgets.php
+++ b/wp-content/plugins/buddypress/bp-groups/bp-groups-widgets.php
@@ -19,10 +19,6 @@ add_action( 'bp_register_widgets', 'groups_register_widgets' );
 /*** GROUPS WIDGET *****************/
 
 class BP_Groups_Widget extends WP_Widget {
-	function bp_groups_widget() {
-		$this->_construct();
-	}
-
 	function __construct() {
 		$widget_ops = array(
 			'description' => __( 'A dynamic list of recently active, popular, and newest groups', 'buddypress' ),
@@ -32,10 +28,19 @@ class BP_Groups_Widget extends WP_Widget {
 
 		if ( is_active_widget( false, false, $this->id_base ) && !is_admin() && !is_network_admin() ) {
 			$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
-			wp_enqueue_script( 'groups_widget_groups_list-js', BP_PLUGIN_URL . "bp-groups/js/widget-groups{$min}.js", array( 'jquery' ), bp_get_version() );
+			wp_enqueue_script( 'groups_widget_groups_list-js', buddypress()->plugin_url . "bp-groups/js/widget-groups{$min}.js", array( 'jquery' ), bp_get_version() );
 		}
 	}
 
+	/**
+	 * PHP4 constructor
+	 *
+	 * For backward compatibility only
+	 */
+	function bp_groups_widget() {
+		$this->_construct();
+	}
+
 	function widget( $args, $instance ) {
 		$user_id = apply_filters( 'bp_group_widget_user_id', '0' );
 
@@ -64,7 +69,7 @@ class BP_Groups_Widget extends WP_Widget {
 
 			<ul id="groups-list" class="item-list">
 				<?php while ( bp_groups() ) : bp_the_group(); ?>
-					<li>
+					<li <?php bp_group_class(); ?>>
 						<div class="item-avatar">
 							<a href="<?php bp_group_permalink() ?>" title="<?php bp_group_name() ?>"><?php bp_group_avatar_thumb() ?></a>
 						</div>
@@ -164,10 +169,19 @@ function groups_ajax_widget_groups_list() {
 		break;
 	}
 
-	if ( bp_has_groups( 'type=' . $type . '&per_page=' . $_POST['max_groups'] . '&max=' . $_POST['max_groups'] ) ) : ?>
+	$per_page = isset( $_POST['max_groups'] ) ? intval( $_POST['max_groups'] ) : 5;
+
+	$groups_args = array(
+		'user_id'  => 0,
+		'type'     => $type,
+		'per_page' => $per_page,
+		'max'      => $per_page,
+	);
+
+	if ( bp_has_groups( $groups_args ) ) : ?>
 		<?php echo "0[[SPLIT]]"; ?>
 		<?php while ( bp_groups() ) : bp_the_group(); ?>
-			<li>
+			<li <?php bp_group_class(); ?>>
 				<div class="item-avatar">
 					<a href="<?php bp_group_permalink() ?>"><?php bp_group_avatar_thumb() ?></a>
 				</div>
diff --git a/wp-content/plugins/buddypress/bp-languages/buddypress.pot b/wp-content/plugins/buddypress/bp-languages/buddypress.pot
index 0ee6edbad17fab65f5c76b9f8ee15ae1b01a5095..6acd1c5c6c47c9f10c6e401afdac50d37f2f4fbd 100644
--- a/wp-content/plugins/buddypress/bp-languages/buddypress.pot
+++ b/wp-content/plugins/buddypress/bp-languages/buddypress.pot
@@ -1,14 +1,14 @@
-# Copyright (C) 2013 BuddyPress
+# Copyright (C) 2014 BuddyPress
 # This file is distributed under the same license as the BuddyPress package.
 msgid ""
 msgstr ""
 "Project-Id-Version: BuddyPress \n"
 "Report-Msgid-Bugs-To: http://wppolyglots.wordpress.com\n"
-"POT-Creation-Date: 2013-07-27 18:35:29+00:00\n"
+"POT-Creation-Date: 2014-04-15 14:30:37+00:00\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2013-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: 2014-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 
@@ -20,66 +20,66 @@ msgstr ""
 msgid "There was an error when deleting that activity"
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:213
+#: bp-activity/bp-activity-actions.php:214
 msgid "The activity item has been marked as spam and is no longer visible."
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:262
-#: bp-templates/bp-legacy/buddypress-functions.php:621
+#: bp-activity/bp-activity-actions.php:269
+#: bp-templates/bp-legacy/buddypress-functions.php:692
 #: bp-themes/bp-default/_inc/ajax.php:276
 msgid "Please enter some content to post."
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:283
+#: bp-activity/bp-activity-actions.php:290
 msgid "Update Posted!"
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:285
+#: bp-activity/bp-activity-actions.php:292
 msgid "There was an error when posting your update, please try again."
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:322
-#: bp-templates/bp-legacy/buddypress-functions.php:669
+#: bp-activity/bp-activity-actions.php:329
+#: bp-templates/bp-legacy/buddypress-functions.php:753
 #: bp-themes/bp-default/_inc/ajax.php:324
 msgid "Please do not leave the comment area blank."
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:333
+#: bp-activity/bp-activity-actions.php:340
 msgid "Reply Posted!"
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:335
-#: bp-templates/bp-legacy/buddypress-functions.php:672
-#: bp-templates/bp-legacy/buddypress-functions.php:681
+#: bp-activity/bp-activity-actions.php:342
+#: bp-templates/bp-legacy/buddypress-functions.php:756
+#: bp-templates/bp-legacy/buddypress-functions.php:765
 #: bp-themes/bp-default/_inc/ajax.php:327
 #: bp-themes/bp-default/_inc/ajax.php:336
 msgid "There was an error posting that reply, please try again."
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:367
+#: bp-activity/bp-activity-actions.php:374
 msgid "Activity marked as favorite."
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:369
+#: bp-activity/bp-activity-actions.php:376
 msgid "There was an error marking that activity as a favorite, please try again."
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:401
+#: bp-activity/bp-activity-actions.php:408
 msgid "Activity removed as favorite."
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:403
+#: bp-activity/bp-activity-actions.php:410
 msgid "There was an error removing that activity as a favorite, please try again."
 msgstr ""
 
 #. translators: Sitewide activity RSS title - "[Site Name] | Site Wide
 #. Activity"
 
-#: bp-activity/bp-activity-actions.php:434
+#: bp-activity/bp-activity-actions.php:440
 msgid "%s | Site Wide Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:437
+#: bp-activity/bp-activity-actions.php:443
 msgid "Activity feed for the entire site."
 msgstr ""
 
@@ -88,314 +88,335 @@ msgstr ""
 #. translators: Group activity RSS title - "[Site Name] | [Group Name] |
 #. Activity"
 
-#: bp-activity/bp-activity-actions.php:465 bp-groups/bp-groups-actions.php:331
+#: bp-activity/bp-activity-actions.php:470 bp-groups/bp-groups-actions.php:389
 msgid "%1$s | %2$s | Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:468
+#: bp-activity/bp-activity-actions.php:473
 msgid "Activity feed for %s."
 msgstr ""
 
 #. translators: Friends activity RSS title - "[Site Name] | [User Display Name]
 #. | Friends Activity"
 
-#: bp-activity/bp-activity-actions.php:499
+#: bp-activity/bp-activity-actions.php:503
 msgid "%1$s | %2$s | Friends Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:502
+#: bp-activity/bp-activity-actions.php:506
 msgid "Activity feed for %s's friends."
 msgstr ""
 
 #. translators: Member groups activity RSS title - "[Site Name] | [User Display
 #. Name] | Groups Activity"
 
-#: bp-activity/bp-activity-actions.php:537
+#: bp-activity/bp-activity-actions.php:540
 msgid "%1$s | %2$s | Group Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:540
+#: bp-activity/bp-activity-actions.php:543
 msgid "Public group activity feed of which %s is a member of."
 msgstr ""
 
+#. translators: User mentions activity RSS title - "[Site Name] | [User Display
+#. Name] | Mentions"
+
+#: bp-activity/bp-activity-actions.php:579
+msgid "%1$s | %2$s | Mentions"
+msgstr ""
+
+#: bp-activity/bp-activity-actions.php:582
+msgid "Activity feed mentioning %s."
+msgstr ""
+
 #. translators: User activity favorites RSS title - "[Site Name] | [User
 #. Display Name] | Favorites"
 
-#: bp-activity/bp-activity-actions.php:608
+#: bp-activity/bp-activity-actions.php:616
 msgid "%1$s | %2$s | Favorites"
 msgstr ""
 
-#: bp-activity/bp-activity-actions.php:611
+#: bp-activity/bp-activity-actions.php:619
 msgid "Activity feed of %s's favorites."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:35 bp-activity/bp-activity-admin.php:36
-#: bp-activity/bp-activity-admin.php:852 bp-activity/bp-activity-admin.php:1167
-#: bp-activity/bp-activity-loader.php:118
-#: bp-activity/bp-activity-loader.php:246
-#: bp-activity/bp-activity-screens.php:284
-#: bp-activity/bp-activity-screens.php:451 bp-core/bp-core-admin.php:409
+#: bp-activity/bp-activity-admin.php:32 bp-activity/bp-activity-admin.php:33
+#: bp-activity/bp-activity-admin.php:906 bp-activity/bp-activity-admin.php:1242
+#: bp-activity/bp-activity-loader.php:139
+#: bp-activity/bp-activity-loader.php:268
+#: bp-activity/bp-activity-screens.php:270
+#: bp-activity/bp-activity-screens.php:437 bp-core/bp-core-admin.php:525
 msgid "Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:85
+#: bp-activity/bp-activity-admin.php:88
 msgid "ERROR: Please type a reply."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:90
+#: bp-activity/bp-activity-admin.php:93
 msgid "ERROR: The item you are trying to reply to cannot be found, or it has been deleted."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:197 bp-activity/bp-activity-admin.php:244
-#: bp-core/admin/bp-core-functions.php:412
-#: bp-core/admin/bp-core-functions.php:430
-#: bp-core/admin/bp-core-functions.php:449
-#: bp-core/admin/bp-core-functions.php:468 bp-groups/bp-groups-admin.php:107
-#: bp-groups/bp-groups-admin.php:143
+#: bp-activity/bp-activity-admin.php:211 bp-activity/bp-activity-admin.php:258
+#: bp-core/admin/bp-core-functions.php:451
+#: bp-core/admin/bp-core-functions.php:469
+#: bp-core/admin/bp-core-functions.php:488
+#: bp-core/admin/bp-core-functions.php:507 bp-groups/bp-groups-admin.php:111
+#: bp-groups/bp-groups-admin.php:146 bp-members/bp-members-admin.php:384
+#: bp-members/bp-members-admin.php:921
 msgid "Overview"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:199
+#: bp-activity/bp-activity-admin.php:213
 msgid "You edit activities made on your site similar to the way you edit a comment. This is useful if you need to change which page the activity links to, or when you notice that the author has made a typographical error."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:200
+#: bp-activity/bp-activity-admin.php:214
 msgid "The two big editing areas for the activity title and content are fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of each box. Use the Screen Options tab to unhide more boxes (Primary Item/Secondary Item, Link, Type, Author ID) or to choose a 1- or 2-column layout for this screen."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:201
+#: bp-activity/bp-activity-admin.php:215
 msgid "You can also moderate the activity from this screen using the Status box, where you can also change the timestamp of the activity."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:206
+#: bp-activity/bp-activity-admin.php:220
 msgid "Item, Link, Type"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:208
+#: bp-activity/bp-activity-admin.php:222
 msgid "<strong>Primary Item/Secondary Item</strong> - These identify the object that created the activity. For example, the fields could reference a comment left on a specific site. Some types of activity may only use one, or none, of these fields."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:209
-msgid "<strong>Link</strong> - Activity generated by blog posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item. Some types of activity may not use this field, even if it has been set."
+#: bp-activity/bp-activity-admin.php:223
+msgid "<strong>Link</strong> - Activity generated by posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item. Some types of activity may not use this field, even if it has been set."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:210
+#: bp-activity/bp-activity-admin.php:224
 msgid "<strong>Type</strong> - Each distinct kind of activity has its own type. For example, <code>created_group</code> is used when a group is created and <code>joined_group</code> is used when a user joins a group."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:211
+#: bp-activity/bp-activity-admin.php:225
 msgid "For information about when and how BuddyPress uses all of these settings, see the Managing Activity link in the panel to the side."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:216 bp-activity/bp-activity-admin.php:261
-#: bp-core/admin/bp-core-functions.php:418
-#: bp-core/admin/bp-core-functions.php:436
-#: bp-core/admin/bp-core-functions.php:455
-#: bp-core/admin/bp-core-functions.php:474 bp-groups/bp-groups-admin.php:115
-#: bp-groups/bp-groups-admin.php:159
+#: bp-activity/bp-activity-admin.php:230 bp-activity/bp-activity-admin.php:275
+#: bp-core/admin/bp-core-functions.php:457
+#: bp-core/admin/bp-core-functions.php:475
+#: bp-core/admin/bp-core-functions.php:494
+#: bp-core/admin/bp-core-functions.php:513 bp-groups/bp-groups-admin.php:119
+#: bp-groups/bp-groups-admin.php:162 bp-members/bp-members-admin.php:393
+#: bp-members/bp-members-admin.php:942
 msgid "For more information:"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:217
+#: bp-activity/bp-activity-admin.php:231
 msgid "<a href=\"http://codex.buddypress.org/buddypress-site-administration/managing-activity/\">Managing Activity</a>"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:218 bp-activity/bp-activity-admin.php:262
-#: bp-core/admin/bp-core-functions.php:420
-#: bp-core/admin/bp-core-functions.php:438
-#: bp-core/admin/bp-core-functions.php:457
-#: bp-core/admin/bp-core-functions.php:476 bp-groups/bp-groups-admin.php:160
+#: bp-activity/bp-activity-admin.php:232 bp-activity/bp-activity-admin.php:276
+#: bp-core/admin/bp-core-functions.php:459
+#: bp-core/admin/bp-core-functions.php:477
+#: bp-core/admin/bp-core-functions.php:496
+#: bp-core/admin/bp-core-functions.php:515 bp-groups/bp-groups-admin.php:163
+#: bp-members/bp-members-admin.php:395 bp-members/bp-members-admin.php:943
 msgid "<a href=\"http://buddypress.org/support/\">Support Forums</a>"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:222
+#: bp-activity/bp-activity-admin.php:236
 msgctxt "activity admin edit screen"
 msgid "Status"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:223
+#: bp-activity/bp-activity-admin.php:237
 msgctxt "activity admin edit screen"
 msgid "Primary Item/Secondary Item"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:224
+#: bp-activity/bp-activity-admin.php:238
 msgctxt "activity admin edit screen"
 msgid "Link"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:225
+#: bp-activity/bp-activity-admin.php:239
 msgctxt "activity admin edit screen"
 msgid "Type"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:226
+#: bp-activity/bp-activity-admin.php:240
 msgctxt "activity admin edit screen"
 msgid "Author ID"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:239
+#: bp-activity/bp-activity-admin.php:253
 msgctxt "Activity items per page (screen options)"
 msgid "Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:246
+#: bp-activity/bp-activity-admin.php:260
 msgid "You can manage activities made on your site similar to the way you manage comments and other content. This screen is customizable in the same ways as other management screens, and you can act on activities using the on-hover action links or the Bulk Actions."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:247
+#: bp-activity/bp-activity-admin.php:261
 msgid "There are many different types of activities. Some are generated automatically by BuddyPress and other plugins, and some are entered directly by a user in the form of status update. To help manage the different activity types, use the filter dropdown box to switch between them."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:253
+#: bp-activity/bp-activity-admin.php:267
 msgid "Moderating Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:255
+#: bp-activity/bp-activity-admin.php:269
 msgid "In the <strong>Activity</strong> column, above each activity it says &#8220;Submitted on,&#8221; followed by the date and time the activity item was generated on your site. Clicking on the date/time link will take you to that activity on your live site. Hovering over any activity gives you options to reply, edit, spam mark, or delete that activity."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:256
+#: bp-activity/bp-activity-admin.php:270
 msgid "In the <strong>In Response To</strong> column, if the activity was in reply to another activity, it shows that activity's author's picture and name, and a link to that activity on your live site. If there is a small bubble, the number in it shows how many other activities are related to this one; these are usually comments. Clicking the bubble will filter the activity screen to show only related activity items."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:582
+#: bp-activity/bp-activity-admin.php:588
 msgid "Editing Activity (ID #%s)"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:593
+#: bp-activity/bp-activity-admin.php:599 bp-activity/bp-activity-admin.php:1243
 msgid "Action"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:600
+#: bp-activity/bp-activity-admin.php:606
 msgid "Content"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:625
+#: bp-activity/bp-activity-admin.php:631
 msgid "No activity found with this ID. <a href=\"%s\">Go back and try again</a>."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:647
+#: bp-activity/bp-activity-admin.php:654
 msgid "View Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:655
+#: bp-activity/bp-activity-admin.php:662
 msgid "Approved"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:656 bp-activity/bp-activity-admin.php:1288
-#: bp-activity/bp-activity-akismet.php:178
-#: bp-activity/bp-activity-akismet.php:207
+#: bp-activity/bp-activity-admin.php:663 bp-activity/bp-activity-admin.php:1398
+#: bp-activity/bp-activity-akismet.php:197
+#: bp-activity/bp-activity-akismet.php:226
 msgid "Spam"
 msgstr ""
 
 #. translators: Publish box date format, see http:php.net/date
 
-#: bp-activity/bp-activity-admin.php:662
+#: bp-activity/bp-activity-admin.php:669 bp-members/bp-members-admin.php:650
+#: bp-members/bp-members-admin.php:711
 msgid "M j, Y @ G:i"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:665
+#: bp-activity/bp-activity-admin.php:672
 msgid "Submitted on: <strong>%1$s</strong>"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:665 bp-activity/bp-activity-admin.php:1281
-#: bp-forums/bp-forums-template.php:1270 bp-groups/bp-groups-admin.php:1338
-#: bp-themes/bp-default/functions.php:509 bp-xprofile/bp-xprofile-admin.php:456
-#: bp-xprofile/bp-xprofile-loader.php:185
-#: bp-xprofile/bp-xprofile-loader.php:245
+#: bp-activity/bp-activity-admin.php:672 bp-activity/bp-activity-admin.php:1391
+#: bp-forums/bp-forums-template.php:2112 bp-groups/bp-groups-admin.php:1396
+#: bp-themes/bp-default/functions.php:509 bp-xprofile/bp-xprofile-admin.php:402
+#: bp-xprofile/bp-xprofile-loader.php:193
+#: bp-xprofile/bp-xprofile-loader.php:271
 msgid "Edit"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:678
+#: bp-activity/bp-activity-admin.php:685
 msgid "Update"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:697
+#: bp-activity/bp-activity-admin.php:705
 msgid "Link"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:699
-msgid "Activity generated by blog posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item."
+#: bp-activity/bp-activity-admin.php:707
+msgid "Activity generated by posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:713
+#: bp-activity/bp-activity-admin.php:722
 msgid "Author ID"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:764
+#: bp-activity/bp-activity-admin.php:791
+msgid "This activity item has a type (%s) that is not registered using bp_activity_set_action(), so no label is available."
+msgstr ""
+
+#: bp-activity/bp-activity-admin.php:816
 msgid "Primary Item ID"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:768
+#: bp-activity/bp-activity-admin.php:820
 msgid "Secondary Item ID"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:771
+#: bp-activity/bp-activity-admin.php:823
 msgid "These identify the object that created this activity. For example, the fields could reference a pair of site and comment IDs."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:809
+#: bp-activity/bp-activity-admin.php:863
 msgid "%s activity item has been permanently deleted."
 msgid_plural "%s activity items have been permanently deleted."
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-activity/bp-activity-admin.php:813
+#: bp-activity/bp-activity-admin.php:867
 msgid "An error occurred when trying to update activity ID #%s."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:816
+#: bp-activity/bp-activity-admin.php:870
 msgid "Errors occurred when trying to update these activity items:"
 msgstr ""
 
 #. Translators: This is a bulleted list of item IDs
 
-#: bp-activity/bp-activity-admin.php:822
+#: bp-activity/bp-activity-admin.php:876
 msgid "#%s"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:831
+#: bp-activity/bp-activity-admin.php:885
 msgid "%s activity item has been successfully spammed."
 msgid_plural "%s activity items have been successfully spammed."
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-activity/bp-activity-admin.php:834
+#: bp-activity/bp-activity-admin.php:888
 msgid "%s activity item has been successfully unspammed."
 msgid_plural "%s activity items have been successfully unspammed."
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-activity/bp-activity-admin.php:837
+#: bp-activity/bp-activity-admin.php:891
 msgid "The activity item has been updated succesfully."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:850
+#: bp-activity/bp-activity-admin.php:904
 msgid "Activity related to ID #%s"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:856 bp-groups/bp-groups-admin.php:630
+#: bp-activity/bp-activity-admin.php:910 bp-groups/bp-groups-admin.php:645
+#: bp-members/bp-members-admin.php:1300
 msgid "Search results for &#8220;%s&#8221;"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:869
+#: bp-activity/bp-activity-admin.php:923
 msgid "Search all Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:880
+#: bp-activity/bp-activity-admin.php:934
 msgid "Reply to Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:884 bp-groups/bp-groups-admin.php:586
+#: bp-activity/bp-activity-admin.php:938 bp-groups/bp-groups-admin.php:599
+#: bp-members/bp-members-admin.php:1425
 #: bp-templates/bp-legacy/buddypress/activity/entry.php:102
 #: bp-templates/bp-legacy/buddypress/forums/index.php:116
 #: bp-themes/bp-default/forums/index.php:134
-#: bp-xprofile/bp-xprofile-classes.php:406
-#: bp-xprofile/bp-xprofile-classes.php:928
+#: bp-xprofile/bp-xprofile-classes.php:506
+#: bp-xprofile/bp-xprofile-classes.php:891
 msgid "Cancel"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:885 bp-activity/bp-activity-admin.php:1278
+#: bp-activity/bp-activity-admin.php:939 bp-activity/bp-activity-admin.php:1385
 #: bp-templates/bp-legacy/buddypress/activity/comment.php:37
 #: bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php:10
 #: bp-themes/bp-default/activity/comment.php:40
@@ -403,261 +424,275 @@ msgstr ""
 msgid "Reply"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1069
+#: bp-activity/bp-activity-admin.php:1132
 msgid "No activities found."
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1133 bp-groups/bp-groups-admin.php:1219
-#: bp-messages/bp-messages-template.php:434
+#: bp-activity/bp-activity-admin.php:1205 bp-groups/bp-groups-admin.php:1267
+#: bp-messages/bp-messages-template.php:538
 msgid "All"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1134
+#: bp-activity/bp-activity-admin.php:1206
 msgid "Spam <span class=\"count\">(%s)</span>"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1149
+#: bp-activity/bp-activity-admin.php:1222
+#: bp-core/admin/bp-core-functions.php:847
 msgid "Mark as Spam"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1150
-#: bp-activity/bp-activity-admin.php:1286
+#: bp-activity/bp-activity-admin.php:1223
+#: bp-activity/bp-activity-admin.php:1396
+#: bp-core/admin/bp-core-functions.php:845
 msgid "Not Spam"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1151
-#: bp-activity/bp-activity-admin.php:1291 bp-groups/bp-groups-admin.php:585
+#: bp-activity/bp-activity-admin.php:1224
+#: bp-activity/bp-activity-admin.php:1401 bp-groups/bp-groups-admin.php:598
 msgid "Delete Permanently"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1166
+#: bp-activity/bp-activity-admin.php:1241
 msgid "Author"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1168
+#: bp-activity/bp-activity-admin.php:1244
 msgid "In Response To"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1206
+#: bp-activity/bp-activity-admin.php:1287
 msgid "Show all activity types"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1213
+#: bp-activity/bp-activity-admin.php:1294
 msgid "Filter"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1227
+#: bp-activity/bp-activity-admin.php:1310
 msgid "Select activity item %1$d"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1291 bp-core/bp-core-cssjs.php:20
+#: bp-activity/bp-activity-admin.php:1341
+msgid "Unregistered action - %s"
+msgstr ""
+
+#: bp-activity/bp-activity-admin.php:1387
+msgid "Replies are disabled for this activity item"
+msgstr ""
+
+#: bp-activity/bp-activity-admin.php:1387
+msgid "Replies disabled"
+msgstr ""
+
+#: bp-activity/bp-activity-admin.php:1401 bp-core/bp-core-cssjs.php:24
 msgid "Are you sure?"
 msgstr ""
 
 #. translators: 2: activity admin ui date/time
 
-#: bp-activity/bp-activity-admin.php:1300
+#: bp-activity/bp-activity-admin.php:1410
 msgid "Submitted on <a href=\"%1$s\">%2$s at %3$s</a>"
 msgstr ""
 
-#: bp-activity/bp-activity-admin.php:1330
+#: bp-activity/bp-activity-admin.php:1442
 msgid "%s related activity"
 msgid_plural "%s related activities"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-activity/bp-activity-admin.php:1341
+#: bp-activity/bp-activity-admin.php:1453
 msgid "<a href=\"%1$s\">View Activity</a>"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:80
+#: bp-activity/bp-activity-akismet.php:86
 msgid "Flagged as spam by Akismet"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:83
+#: bp-activity/bp-activity-akismet.php:89
 msgid "Cleared by Akismet"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:89
+#: bp-activity/bp-activity-akismet.php:95
 msgid "Flagged as spam by %s"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:91
+#: bp-activity/bp-activity-akismet.php:97
 msgid "Un-spammed by %s"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:100
+#: bp-activity/bp-activity-akismet.php:106
 msgid "History"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:345
+#: bp-activity/bp-activity-akismet.php:373
 msgid "%s reported this activity as spam"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:361
+#: bp-activity/bp-activity-akismet.php:390
 msgid "%s reported this activity as not spam"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:384
+#: bp-activity/bp-activity-akismet.php:414
 msgid "Akismet caught this item as spam"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:389
+#: bp-activity/bp-activity-akismet.php:419
 msgid "Akismet cleared this item"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:394
+#: bp-activity/bp-activity-akismet.php:424
 msgid "Akismet was unable to check this item (response: %s), will automatically retry again later."
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:502
+#: bp-activity/bp-activity-akismet.php:538
 msgid "Activity History"
 msgstr ""
 
-#: bp-activity/bp-activity-akismet.php:520
+#: bp-activity/bp-activity-akismet.php:558
 msgctxt "x hours ago - akismet cleared this item"
 msgid "<span>%1$s</span> &mdash; %2$s"
 msgstr ""
 
-#: bp-activity/bp-activity-classes.php:120
-#: bp-activity/bp-activity-template.php:120 bp-groups/bp-groups-classes.php:318
-#: bp-groups/bp-groups-template.php:114
+#: bp-activity/bp-activity-classes.php:280
+#: bp-activity/bp-activity-template.php:139 bp-groups/bp-groups-classes.php:646
+#: bp-groups/bp-groups-functions.php:418 bp-groups/bp-groups-template.php:112
+#: bp-groups/bp-groups-template.php:2024 bp-groups/bp-groups-template.php:2992
+#: bp-groups/bp-groups-template.php:3260
 msgid "Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details."
 msgstr ""
 
-#: bp-activity/bp-activity-classes.php:844
+#: bp-activity/bp-activity-classes.php:1427
 msgid "RSS feed 'id' must be defined"
 msgstr ""
 
-#: bp-activity/bp-activity-classes.php:941
+#: bp-activity/bp-activity-classes.php:1540
 msgid "In reply to"
 msgstr ""
 
-#: bp-activity/bp-activity-filters.php:361
+#: bp-activity/bp-activity-filters.php:380
 msgid "[Read more]"
 msgstr ""
 
-#: bp-activity/bp-activity-filters.php:366
+#: bp-activity/bp-activity-filters.php:385
 msgid "&hellip;"
 msgstr ""
 
-#: bp-activity/bp-activity-functions.php:223
-msgid "@%s Mentions"
-msgstr ""
-
-#: bp-activity/bp-activity-functions.php:226
-msgid "You have %1$d new mentions"
+#: bp-activity/bp-activity-filters.php:567
+msgid "Load Newest"
 msgstr ""
 
-#: bp-activity/bp-activity-functions.php:230
-msgid "%1$s mentioned you"
-msgstr ""
-
-#: bp-activity/bp-activity-functions.php:867
+#: bp-activity/bp-activity-functions.php:837
 msgid "Posted a status update"
 msgstr ""
 
-#: bp-activity/bp-activity-functions.php:868
+#: bp-activity/bp-activity-functions.php:844
 msgid "Replied to a status update"
 msgstr ""
 
-#: bp-activity/bp-activity-functions.php:1119
+#: bp-activity/bp-activity-functions.php:895
 msgid "%s posted an update"
 msgstr ""
 
-#: bp-activity/bp-activity-functions.php:1188
-#: tests/testcases/activity/class.BP_Activity_Activity.php:202
+#: bp-activity/bp-activity-functions.php:909
+#: tests/testcases/activity/class.BP_Activity_Activity.php:216
 msgid "%s posted a new activity comment"
 msgstr ""
 
-#: bp-activity/bp-activity-functions.php:1565
+#: bp-activity/bp-activity-functions.php:1671
 msgid "Thumbnail"
 msgstr ""
 
 #: bp-activity/bp-activity-loader.php:30
-#: bp-core/admin/bp-core-components.php:371
+#: bp-core/admin/bp-core-components.php:380
 msgid "Activity Streams"
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:93
+#: bp-activity/bp-activity-loader.php:109
+msgctxt "component directory title"
+msgid "Sitewide Activity"
+msgstr ""
+
+#: bp-activity/bp-activity-loader.php:111
 msgid "Search Activity..."
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:144
-#: bp-activity/bp-activity-loader.php:264
+#: bp-activity/bp-activity-loader.php:165
+#: bp-activity/bp-activity-loader.php:286
 msgid "Personal"
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:155
-#: bp-activity/bp-activity-loader.php:238
+#: bp-activity/bp-activity-loader.php:176
+#: bp-activity/bp-activity-loader.php:260
 #: bp-templates/bp-legacy/buddypress/activity/index.php:59
 #: bp-themes/bp-default/activity/index.php:79
 msgid "Mentions"
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:167
-#: bp-activity/bp-activity-loader.php:272
+#: bp-activity/bp-activity-loader.php:188
+#: bp-activity/bp-activity-loader.php:294
 msgid "Favorites"
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:179
-#: bp-activity/bp-activity-loader.php:281 bp-friends/bp-friends-loader.php:164
-#: bp-friends/bp-friends-screens.php:83
+#: bp-activity/bp-activity-loader.php:200
+#: bp-activity/bp-activity-loader.php:303 bp-friends/bp-friends-loader.php:188
+#: bp-friends/bp-friends-screens.php:85
 msgid "Friends"
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:192
-#: bp-activity/bp-activity-loader.php:291 bp-core/bp-core-template.php:246
-#: bp-groups/bp-groups-activity.php:150 bp-groups/bp-groups-activity.php:186
-#: bp-groups/bp-groups-activity.php:222 bp-groups/bp-groups-activity.php:258
-#: bp-groups/bp-groups-admin.php:35 bp-groups/bp-groups-admin.php:36
-#: bp-groups/bp-groups-admin.php:623 bp-groups/bp-groups-loader.php:517
-#: bp-groups/bp-groups-screens.php:895 bp-groups/bp-groups-screens.php:1027
-#: bp-groups/bp-groups-screens.php:1029 bp-groups/bp-groups-screens.php:1088
-#: bp-groups/bp-groups-screens.php:1090 bp-groups/bp-groups-widgets.php:48
-#: bp-groups/bp-groups-widgets.php:119
+#: bp-activity/bp-activity-loader.php:213
+#: bp-activity/bp-activity-loader.php:313 bp-core/bp-core-template.php:389
+#: bp-groups/bp-groups-admin.php:32 bp-groups/bp-groups-admin.php:33
+#: bp-groups/bp-groups-admin.php:638 bp-groups/bp-groups-loader.php:365
+#: bp-groups/bp-groups-loader.php:540 bp-groups/bp-groups-notifications.php:377
+#: bp-groups/bp-groups-notifications.php:413
+#: bp-groups/bp-groups-notifications.php:449
+#: bp-groups/bp-groups-notifications.php:485
+#: bp-groups/bp-groups-screens.php:936 bp-groups/bp-groups-screens.php:1122
+#: bp-groups/bp-groups-widgets.php:53 bp-groups/bp-groups-widgets.php:124
 msgid "Groups"
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:236
+#: bp-activity/bp-activity-loader.php:258
 msgid "Mentions <span class=\"count\">%s</span>"
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:316
+#: bp-activity/bp-activity-loader.php:337
 msgid "My Activity"
 msgstr ""
 
-#: bp-activity/bp-activity-loader.php:321
-#: bp-activity/bp-activity-template.php:985
-#: bp-activity/bp-activity-template.php:1121
-#: bp-activity/bp-activity-template.php:1132 bp-blogs/bp-blogs-loader.php:218
-#: bp-forums/bp-forums-loader.php:218 bp-forums/bp-forums-template.php:487
-#: bp-forums/bp-forums-template.php:604 bp-forums/bp-forums-template.php:1200
-#: bp-friends/bp-friends-loader.php:212 bp-groups/bp-groups-loader.php:582
-#: bp-groups/bp-groups-template.php:770 bp-groups/bp-groups-template.php:793
-#: bp-groups/bp-groups-template.php:1222 bp-groups/bp-groups-template.php:1238
-#: bp-groups/bp-groups-template.php:1287 bp-groups/bp-groups-template.php:1303
-#: bp-groups/bp-groups-template.php:2012 bp-groups/bp-groups-template.php:2021
-#: bp-groups/bp-groups-template.php:2030 bp-groups/bp-groups-template.php:2778
-#: bp-members/bp-members-buddybar.php:90 bp-members/bp-members-loader.php:198
+#: bp-activity/bp-activity-loader.php:342
+#: bp-activity/bp-activity-template.php:1208
+#: bp-activity/bp-activity-template.php:1358
+#: bp-activity/bp-activity-template.php:1369 bp-blogs/bp-blogs-loader.php:236
+#: bp-forums/bp-forums-loader.php:245 bp-forums/bp-forums-template.php:730
+#: bp-forums/bp-forums-template.php:960 bp-forums/bp-forums-template.php:1990
+#: bp-friends/bp-friends-loader.php:234 bp-groups/bp-groups-loader.php:601
+#: bp-groups/bp-groups-template.php:800 bp-groups/bp-groups-template.php:837
+#: bp-groups/bp-groups-template.php:1266 bp-groups/bp-groups-template.php:1282
+#: bp-groups/bp-groups-template.php:1331 bp-groups/bp-groups-template.php:1347
+#: bp-groups/bp-groups-template.php:2222 bp-groups/bp-groups-template.php:2231
+#: bp-groups/bp-groups-template.php:2240 bp-groups/bp-groups-template.php:3151
+#: bp-members/bp-members-buddybar.php:64 bp-members/bp-members-loader.php:224
 #: bp-members/bp-members-template.php:520
-#: bp-members/bp-members-template.php:820
-#: bp-members/bp-members-template.php:839
-#: bp-messages/bp-messages-loader.php:264
-#: bp-messages/bp-messages-template.php:326
+#: bp-members/bp-members-template.php:881
+#: bp-members/bp-members-template.php:900
+#: bp-messages/bp-messages-loader.php:265
+#: bp-messages/bp-messages-template.php:417
+#: bp-notifications/bp-notifications-loader.php:236
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:185
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:212
 #: bp-themes/bp-default/groups/single/admin.php:185
 #: bp-themes/bp-default/groups/single/admin.php:212
-#: bp-xprofile/bp-xprofile-loader.php:277
+#: bp-xprofile/bp-xprofile-loader.php:317
 msgid "Profile picture of %s"
 msgstr ""
 
-#: bp-activity/bp-activity-notifications.php:74
+#: bp-activity/bp-activity-notifications.php:73
 msgid "%s mentioned you in an update"
 msgstr ""
 
-#: bp-activity/bp-activity-notifications.php:77 bp-core/deprecated/1.5.php:354
+#: bp-activity/bp-activity-notifications.php:76 bp-core/deprecated/1.5.php:354
 msgid ""
 "%1$s mentioned you in the group \"%2$s\":\n"
 "\n"
@@ -668,7 +703,7 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-activity/bp-activity-notifications.php:87
+#: bp-activity/bp-activity-notifications.php:86
 msgid ""
 "%1$s mentioned you in an update:\n"
 "\n"
@@ -679,25 +714,25 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-activity/bp-activity-notifications.php:100
-#: bp-activity/bp-activity-notifications.php:178
+#: bp-activity/bp-activity-notifications.php:99
+#: bp-activity/bp-activity-notifications.php:177
 #: bp-activity/bp-activity-notifications.php:226 bp-core/deprecated/1.5.php:364
-#: bp-friends/bp-friends-notifications.php:44
-#: bp-friends/bp-friends-notifications.php:82
-#: bp-groups/bp-groups-notifications.php:42
-#: bp-groups/bp-groups-notifications.php:92
-#: bp-groups/bp-groups-notifications.php:150
-#: bp-groups/bp-groups-notifications.php:198
-#: bp-groups/bp-groups-notifications.php:254
-#: bp-messages/bp-messages-notifications.php:66
+#: bp-friends/bp-friends-notifications.php:56
+#: bp-friends/bp-friends-notifications.php:105
+#: bp-groups/bp-groups-notifications.php:44
+#: bp-groups/bp-groups-notifications.php:108
+#: bp-groups/bp-groups-notifications.php:173
+#: bp-groups/bp-groups-notifications.php:232
+#: bp-groups/bp-groups-notifications.php:295
+#: bp-messages/bp-messages-notifications.php:85
 msgid "To disable these notifications please log in and go to: %s"
 msgstr ""
 
-#: bp-activity/bp-activity-notifications.php:165
+#: bp-activity/bp-activity-notifications.php:164
 msgid "%s replied to one of your updates"
 msgstr ""
 
-#: bp-activity/bp-activity-notifications.php:166
+#: bp-activity/bp-activity-notifications.php:165
 msgid ""
 "%1$s replied to one of your updates:\n"
 "\n"
@@ -723,599 +758,678 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-activity/bp-activity-screens.php:245
+#: bp-activity/bp-activity-notifications.php:280
+msgid "@%s Mentions"
+msgstr ""
+
+#: bp-activity/bp-activity-notifications.php:283
+msgid "You have %1$d new mentions"
+msgstr ""
+
+#: bp-activity/bp-activity-notifications.php:287
+msgid "%1$s mentioned you"
+msgstr ""
+
+#: bp-activity/bp-activity-screens.php:231
 msgid "You do not have access to this activity."
 msgstr ""
 
-#: bp-activity/bp-activity-screens.php:285 bp-blogs/bp-blogs-template.php:683
-#: bp-friends/bp-friends-screens.php:84 bp-groups/bp-groups-screens.php:896
+#: bp-activity/bp-activity-screens.php:271 bp-blogs/bp-blogs-template.php:997
+#: bp-friends/bp-friends-screens.php:86 bp-groups/bp-groups-screens.php:937
 #: bp-messages/bp-messages-screens.php:169
-#: bp-templates/bp-legacy/buddypress/members/register.php:223
-#: bp-themes/bp-default/registration/register.php:228
+#: bp-templates/bp-legacy/buddypress/members/register.php:148
+#: bp-themes/bp-default/registration/register.php:232
 msgid "Yes"
 msgstr ""
 
-#: bp-activity/bp-activity-screens.php:286 bp-blogs/bp-blogs-template.php:687
-#: bp-friends/bp-friends-screens.php:85 bp-groups/bp-groups-screens.php:897
+#: bp-activity/bp-activity-screens.php:272 bp-blogs/bp-blogs-template.php:1001
+#: bp-friends/bp-friends-screens.php:87 bp-groups/bp-groups-screens.php:938
 #: bp-messages/bp-messages-screens.php:170
-#: bp-templates/bp-legacy/buddypress/members/register.php:224
-#: bp-themes/bp-default/registration/register.php:229
+#: bp-templates/bp-legacy/buddypress/members/register.php:149
+#: bp-themes/bp-default/registration/register.php:233
 msgid "No"
 msgstr ""
 
-#: bp-activity/bp-activity-screens.php:294
+#: bp-activity/bp-activity-screens.php:280
 msgid "A member mentions you in an update using \"@%s\""
 msgstr ""
 
-#: bp-activity/bp-activity-screens.php:302
+#: bp-activity/bp-activity-screens.php:288
 msgid "A member replies to an update or comment you've posted"
 msgstr ""
 
-#: bp-activity/bp-activity-screens.php:398
-msgid "Sitewide Activity"
-msgstr ""
-
-#: bp-activity/bp-activity-template.php:221
+#: bp-activity/bp-activity-template.php:266
 msgctxt "Activity pagination previous text"
 msgid "&larr;"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:222
+#: bp-activity/bp-activity-template.php:267
 msgctxt "Activity pagination next text"
 msgid "&rarr;"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:536
-msgid "Viewing item %1$s to %2$s (of %3$s items)"
-msgstr ""
+#: bp-activity/bp-activity-template.php:737
+msgid "Viewing item %1$s to %2$s (of %3$s item)"
+msgid_plural "Viewing item %1$s to %2$s (of %3$s items)"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-activity/bp-activity-template.php:985
+#: bp-activity/bp-activity-template.php:1208
 msgid "Profile picture"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:1097
+#: bp-activity/bp-activity-template.php:1334
 msgid "Group logo"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:1100 bp-groups/bp-groups-admin.php:1352
-#: bp-groups/bp-groups-template.php:516
+#: bp-activity/bp-activity-template.php:1337 bp-groups/bp-groups-admin.php:1410
+#: bp-groups/bp-groups-template.php:518
 msgid "Group logo of %s"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:1111
+#: bp-activity/bp-activity-template.php:1348
 msgid "Profile picture of the author of the site %s"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:1336
+#: bp-activity/bp-activity-template.php:1578
 msgid "View Discussion"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:2205
-#: bp-forums/bp-forums-template.php:1271 bp-groups/bp-groups-admin.php:1237
-#: bp-groups/bp-groups-admin.php:1341 bp-groups/bp-groups-template.php:1486
+#: bp-activity/bp-activity-template.php:2480
+#: bp-forums/bp-forums-template.php:2113 bp-groups/bp-groups-admin.php:1286
+#: bp-groups/bp-groups-admin.php:1399 bp-groups/bp-groups-template.php:1530
+#: bp-members/admin/bp-members-classes.php:148
+#: bp-members/admin/bp-members-classes.php:280
+#: bp-members/admin/bp-members-classes.php:466
+#: bp-members/admin/bp-members-classes.php:591
+#: bp-notifications/bp-notifications-template.php:826
 #: bp-templates/bp-legacy/buddypress/activity/comment.php:43
 #: bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php:51
 #: bp-templates/bp-legacy/buddypress/members/single/messages/single.php:24
 #: bp-themes/bp-default/activity/comment.php:46
 #: bp-themes/bp-default/members/single/messages/messages-loop.php:51
 #: bp-themes/bp-default/members/single/messages/single.php:24
-#: bp-xprofile/bp-xprofile-admin.php:460
+#: bp-xprofile/bp-xprofile-admin.php:406
 msgid "Delete"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:2252
+#: bp-activity/bp-activity-template.php:2528
 #: bp-core/admin/bp-core-slugs.php:109 bp-core/admin/bp-core-slugs.php:172
-#: bp-core/bp-core-loader.php:226 bp-members/bp-members-loader.php:172
-#: bp-members/bp-members-template.php:625
-#: bp-templates/bp-legacy/buddypress-functions.php:237
+#: bp-core/bp-core-loader.php:244 bp-members/bp-members-loader.php:198
+#: bp-members/bp-members-template.php:649
+#: bp-templates/bp-legacy/buddypress-functions.php:248
 #: bp-themes/bp-default/activity/entry.php:37
 #: bp-themes/bp-default/functions.php:166
-#: bp-xprofile/bp-xprofile-loader.php:175
-#: bp-xprofile/bp-xprofile-loader.php:237
+#: bp-xprofile/bp-xprofile-loader.php:183
+#: bp-xprofile/bp-xprofile-loader.php:263
 msgid "View"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:2346
+#: bp-activity/bp-activity-template.php:2626
 msgid "Clear Filter"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:2537
+#: bp-activity/bp-activity-template.php:2852
 msgid "a user"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:2577
+#: bp-activity/bp-activity-template.php:2906
 msgid "Send a public message on your activity stream."
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:2578
+#: bp-activity/bp-activity-template.php:2907
 msgid "Public Message"
 msgstr ""
 
-#: bp-activity/bp-activity-template.php:3000
+#: bp-activity/bp-activity-template.php:3360
 msgid "Site Wide Activity RSS Feed"
 msgstr ""
 
-#: bp-blogs/bp-blogs-activity.php:31
+#: bp-blogs/bp-blogs-activity.php:34
 msgid "New site created"
 msgstr ""
 
-#: bp-blogs/bp-blogs-activity.php:34
+#: bp-blogs/bp-blogs-activity.php:42
 msgid "New post published"
 msgstr ""
 
-#: bp-blogs/bp-blogs-activity.php:35
+#: bp-blogs/bp-blogs-activity.php:49
 msgid "New post comment posted"
 msgstr ""
 
-#: bp-blogs/bp-blogs-buddybar.php:43 bp-blogs/bp-blogs-loader.php:131
-#: bp-blogs/bp-blogs-loader.php:179 bp-blogs/bp-blogs-loader.php:209
-msgid "My Sites"
+#: bp-blogs/bp-blogs-activity.php:69
+msgid "%s created the site %s"
 msgstr ""
 
-#: bp-blogs/bp-blogs-buddybar.php:55 bp-core/bp-core-buddybar.php:545
-msgid "Dashboard"
+#: bp-blogs/bp-blogs-activity.php:128 bp-blogs/bp-blogs-functions.php:452
+msgid "%1$s wrote a new post, %2$s, on the site %3$s"
 msgstr ""
 
-#: bp-blogs/bp-blogs-buddybar.php:56 bp-core/bp-core-buddybar.php:549
-msgid "New Post"
+#: bp-blogs/bp-blogs-activity.php:130 bp-blogs/bp-blogs-functions.php:454
+msgid "%1$s wrote a new post, %2$s"
 msgstr ""
 
-#: bp-blogs/bp-blogs-buddybar.php:57 bp-core/bp-core-buddybar.php:550
-msgid "Manage Posts"
+#: bp-blogs/bp-blogs-activity.php:195
+msgid "%1$s commented on the post, %2$s, on the site %3$s"
 msgstr ""
 
-#: bp-blogs/bp-blogs-buddybar.php:58 bp-core/bp-core-buddybar.php:551
-msgid "Manage Comments"
+#: bp-blogs/bp-blogs-activity.php:197
+msgid "%1$s commented on the post, %2$s"
 msgstr ""
 
-#: bp-blogs/bp-blogs-buddybar.php:71
-msgid "Create a Site!"
+#: bp-blogs/bp-blogs-buddybar.php:42 bp-blogs/bp-blogs-loader.php:149
+#: bp-blogs/bp-blogs-loader.php:199 bp-blogs/bp-blogs-loader.php:227
+msgid "My Sites"
 msgstr ""
 
-#: bp-blogs/bp-blogs-functions.php:175
-msgid "%s created the site %s"
+#: bp-blogs/bp-blogs-buddybar.php:54 bp-core/bp-core-buddybar.php:621
+msgid "Dashboard"
 msgstr ""
 
-#: bp-blogs/bp-blogs-functions.php:252
-msgid "%1$s wrote a new post, %2$s, on the site %3$s"
+#: bp-blogs/bp-blogs-buddybar.php:55 bp-core/bp-core-buddybar.php:625
+msgid "New Post"
 msgstr ""
 
-#: bp-blogs/bp-blogs-functions.php:254
-msgid "%1$s wrote a new post, %2$s"
+#: bp-blogs/bp-blogs-buddybar.php:56 bp-core/bp-core-buddybar.php:626
+msgid "Manage Posts"
 msgstr ""
 
-#: bp-blogs/bp-blogs-functions.php:360
-msgid "%1$s commented on the post, %2$s, on the site %3$s"
+#: bp-blogs/bp-blogs-buddybar.php:57 bp-core/bp-core-buddybar.php:627
+msgid "Manage Comments"
 msgstr ""
 
-#: bp-blogs/bp-blogs-functions.php:362
-msgid "%1$s commented on the post, %2$s"
+#: bp-blogs/bp-blogs-buddybar.php:70
+msgid "Create a Site!"
 msgstr ""
 
-#: bp-blogs/bp-blogs-loader.php:25 bp-core/admin/bp-core-components.php:383
+#: bp-blogs/bp-blogs-loader.php:25 bp-core/admin/bp-core-components.php:396
 msgid "Site Tracking"
 msgstr ""
 
-#: bp-blogs/bp-blogs-loader.php:58
+#: bp-blogs/bp-blogs-loader.php:68
 msgid "Search sites..."
 msgstr ""
 
-#: bp-blogs/bp-blogs-loader.php:111
+#: bp-blogs/bp-blogs-loader.php:129
 msgid "Sites <span>%d</span>"
 msgstr ""
 
-#: bp-blogs/bp-blogs-loader.php:171
+#: bp-blogs/bp-blogs-loader.php:191 bp-blogs/bp-blogs-screens.php:144
+#: bp-blogs/bp-blogs-screens.php:204 bp-blogs/bp-blogs-screens.php:206
 msgid "Sites"
 msgstr ""
 
-#: bp-blogs/bp-blogs-loader.php:188 bp-blogs/bp-blogs-screens.php:135
-#: bp-blogs/bp-blogs-screens.php:196
-msgid "Create a Blog"
-msgstr ""
-
-#: bp-blogs/bp-blogs-screens.php:135 bp-blogs/bp-blogs-screens.php:137
-#: bp-blogs/bp-blogs-screens.php:196 bp-blogs/bp-blogs-screens.php:198
-#: bp-core/bp-core-template.php:249
-msgid "Blogs"
+#: bp-blogs/bp-blogs-loader.php:208 bp-blogs/bp-blogs-screens.php:204
+#: bp-blogs/bp-blogs-template.php:1114 bp-blogs/bp-blogs-template.php:1182
+#: bp-blogs/bp-blogs-template.php:1183 bp-core/bp-core-filters.php:466
+#: bp-themes/bp-default/blogs/create.php:21
+#: bp-themes/bp-default/blogs/index.php:21
+msgid "Create a Site"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:136
+#: bp-blogs/bp-blogs-template.php:218
 msgctxt "Blog pagination previous text"
 msgid "&larr;"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:137
+#: bp-blogs/bp-blogs-template.php:219
 msgctxt "Blog pagination next text"
 msgid "&rarr;"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:261
-msgid "Viewing site %1$s to %2$s (of %3$s sites)"
-msgstr ""
+#: bp-blogs/bp-blogs-template.php:439
+msgid "Viewing site %1$s to %2$s (of %3$s site)"
+msgid_plural "Viewing site %1$s to %2$s (of %3$s sites)"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-blogs/bp-blogs-template.php:285
+#: bp-blogs/bp-blogs-template.php:504
 msgid "Profile picture of site author %s"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:403 bp-core/bp-core-classes.php:774
-#: bp-groups/bp-groups-widgets.php:80 bp-groups/bp-groups-widgets.php:183
-#: bp-members/bp-members-template.php:596
-#: bp-members/bp-members-template.php:871
+#: bp-blogs/bp-blogs-template.php:648 bp-core/bp-core-classes.php:816
+#: bp-groups/bp-groups-template.php:3368 bp-groups/bp-groups-widgets.php:85
+#: bp-groups/bp-groups-widgets.php:197 bp-members/bp-members-template.php:616
+#: bp-members/bp-members-template.php:932
 #: bp-templates/bp-legacy/buddypress/groups/groups-loop.php:47
 #: bp-templates/bp-legacy/buddypress/groups/single/group-header.php:42
 #: bp-themes/bp-default/groups/groups-loop.php:47
 #: bp-themes/bp-default/groups/single/group-header.php:42
+#: tests/testcases/members/template.php:112
+#: tests/testcases/members/template.php:127
 msgid "active %s"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:415
+#: bp-blogs/bp-blogs-template.php:668
 msgid "Latest Post: %s"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:609
+#: bp-blogs/bp-blogs-template.php:915
 msgid "There was a problem, please correct the form below and try again."
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:612
+#: bp-blogs/bp-blogs-template.php:918
 msgid "By filling out the form below, you can <strong>add a site to your account</strong>. There is no limit to the number of sites that you can have, so create to your heart's content, but blog responsibly!"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:614
+#: bp-blogs/bp-blogs-template.php:920
 msgid "If you&#8217;re not going to use a great domain, leave it for a new user. Now have at it!"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:623
+#: bp-blogs/bp-blogs-template.php:929
 msgid "Create Site"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:637
+#: bp-blogs/bp-blogs-template.php:951
 msgid "Site Name:"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:639
+#: bp-blogs/bp-blogs-template.php:953
 msgid "Site Domain:"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:653
+#: bp-blogs/bp-blogs-template.php:967
 msgid "Your address will be "
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:656
+#: bp-blogs/bp-blogs-template.php:970
 msgid "blogname"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:658
+#: bp-blogs/bp-blogs-template.php:972
 msgid "domain."
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:661
+#: bp-blogs/bp-blogs-template.php:975
 msgid "Must be at least 4 characters, letters and numbers only. It cannot be changed so choose carefully!)"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:667
+#: bp-blogs/bp-blogs-template.php:981
 msgid "Site Title:"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:678
+#: bp-blogs/bp-blogs-template.php:992
 msgid "Privacy:"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:679
-#: bp-templates/bp-legacy/buddypress/members/register.php:220
-#: bp-themes/bp-default/registration/register.php:225
+#: bp-blogs/bp-blogs-template.php:993
+#: bp-templates/bp-legacy/buddypress/members/register.php:145
+#: bp-themes/bp-default/registration/register.php:229
 msgid "I would like my site to appear in search engines, and in public listings around this network."
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:762
+#: bp-blogs/bp-blogs-template.php:1100
 msgid "Congratulations! You have successfully registered a new site."
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:764
+#: bp-blogs/bp-blogs-template.php:1102
 msgid "<a href=\"%1$s\">%2$s</a> is your new site.  <a href=\"%3$s\">Login</a> as \"%4$s\" using your existing password."
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:773 bp-core/bp-core-filters.php:378
-#: bp-themes/bp-default/blogs/create.php:21
-#: bp-themes/bp-default/blogs/index.php:21
-msgid "Create a Site"
-msgstr ""
-
-#: bp-blogs/bp-blogs-template.php:785
+#: bp-blogs/bp-blogs-template.php:1131
 msgid "%s's Sites"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:786
+#: bp-blogs/bp-blogs-template.php:1132
 msgid "%s's Recent Posts"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:787
+#: bp-blogs/bp-blogs-template.php:1133
 msgid "%s's Recent Comments"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:801 bp-core/deprecated/1.5.php:417
-#: bp-forums/bp-forums-template.php:1321 bp-groups/bp-groups-template.php:2503
-#: bp-members/bp-members-template.php:710
-#: bp-messages/bp-messages-template.php:367 bp-themes/bp-default/header.php:30
+#: bp-blogs/bp-blogs-template.php:1149 bp-core/deprecated/1.5.php:417
+#: bp-forums/bp-forums-template.php:2196 bp-groups/bp-groups-template.php:2772
+#: bp-members/bp-members-template.php:771
+#: bp-messages/bp-messages-template.php:471 bp-themes/bp-default/header.php:30
 #: bp-themes/bp-default/searchform.php:5
 msgid "Search"
 msgstr ""
 
-#: bp-blogs/bp-blogs-template.php:834 bp-blogs/bp-blogs-template.php:835
+#: bp-blogs/bp-blogs-template.php:1232 bp-blogs/bp-blogs-template.php:1233
 msgid "Visit Site"
 msgstr ""
 
-#: bp-blogs/bp-blogs-widgets.php:29
+#: bp-blogs/bp-blogs-template.php:1288
+msgid "%s site"
+msgid_plural "%s sites"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-blogs/bp-blogs-widgets.php:34
 msgid "A list of recently published posts from across your network."
 msgstr ""
 
-#: bp-blogs/bp-blogs-widgets.php:32
+#: bp-blogs/bp-blogs-widgets.php:37
 msgctxt "widget name"
 msgid "(BuddyPress) Recent Networkwide Posts"
 msgstr ""
 
-#: bp-blogs/bp-blogs-widgets.php:37 bp-blogs/bp-blogs-widgets.php:97
+#: bp-blogs/bp-blogs-widgets.php:50 bp-blogs/bp-blogs-widgets.php:122
 msgid "Recent Networkwide Posts"
 msgstr ""
 
-#: bp-blogs/bp-blogs-widgets.php:78
+#: bp-blogs/bp-blogs-widgets.php:91
 msgid "Sorry, there were no posts found. Why not write one?"
 msgstr ""
 
-#: bp-blogs/bp-blogs-widgets.php:108
+#: bp-blogs/bp-blogs-widgets.php:133
 msgctxt "Label for the Title field of the Recent Networkwide Posts widget"
 msgid "Title:"
 msgstr ""
 
-#: bp-blogs/bp-blogs-widgets.php:109
+#: bp-blogs/bp-blogs-widgets.php:134
 msgid "Link widget title to Blogs directory"
 msgstr ""
 
-#: bp-blogs/bp-blogs-widgets.php:110
+#: bp-blogs/bp-blogs-widgets.php:135
 msgid "Max posts to show:"
 msgstr ""
 
 #: bp-core/admin/bp-core-components.php:26
-#: bp-core/admin/bp-core-functions.php:354
+#: bp-core/admin/bp-core-functions.php:389
 msgid "Components"
 msgstr ""
 
 #: bp-core/admin/bp-core-components.php:32
-#: bp-core/admin/bp-core-settings.php:267 bp-core/admin/bp-core-slugs.php:32
+#: bp-core/admin/bp-core-settings.php:281 bp-core/admin/bp-core-slugs.php:32
+#: bp-templates/bp-legacy/buddypress/members/single/settings/profile.php:42
+#: bp-themes/bp-default/members/single/settings/profile.php:92
 msgid "Save Settings"
 msgstr ""
 
 #: bp-core/admin/bp-core-components.php:59
-#: bp-core/admin/bp-core-components.php:355
+#: bp-core/admin/bp-core-components.php:364
 #: bp-xprofile/bp-xprofile-loader.php:41
 msgid "Extended Profiles"
 msgstr ""
 
 #: bp-core/admin/bp-core-components.php:60
-#: bp-core/admin/bp-core-components.php:356
+#: bp-core/admin/bp-core-components.php:365
 msgid "Customize your community with fully editable profile fields that allow your users to describe themselves."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:136
+#: bp-core/admin/bp-core-components.php:63
+#: bp-core/admin/bp-core-components.php:368
+msgid "Account Settings"
+msgstr ""
+
+#: bp-core/admin/bp-core-components.php:64
+#: bp-core/admin/bp-core-components.php:369
+msgid "Allow your users to modify their account and notification settings directly from within their profiles."
+msgstr ""
+
+#: bp-core/admin/bp-core-components.php:67
+#: bp-core/admin/bp-core-components.php:384
+#: bp-notifications/bp-notifications-buddybar.php:28
+#: bp-notifications/bp-notifications-loader.php:26
+#: bp-notifications/bp-notifications-loader.php:113
+#: bp-notifications/bp-notifications-loader.php:188
+#: bp-notifications/bp-notifications-loader.php:231
+msgid "Notifications"
+msgstr ""
+
+#: bp-core/admin/bp-core-components.php:68
+#: bp-core/admin/bp-core-components.php:385
+msgid "Notify members of relevant activity with a toolbar bubble and/or via email, and allow them to customize their notification settings."
+msgstr ""
+
+#: bp-core/admin/bp-core-components.php:144
 msgctxt "plugins"
 msgid "All <span class=\"count\">(%s)</span>"
 msgid_plural "All <span class=\"count\">(%s)</span>"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/admin/bp-core-components.php:137
+#: bp-core/admin/bp-core-components.php:145
 msgid "Active <span class=\"count\">(%s)</span>"
 msgid_plural "Active <span class=\"count\">(%s)</span>"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/admin/bp-core-components.php:138
+#: bp-core/admin/bp-core-components.php:146
 msgid "Inactive <span class=\"count\">(%s)</span>"
 msgid_plural "Inactive <span class=\"count\">(%s)</span>"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/admin/bp-core-components.php:139
+#: bp-core/admin/bp-core-components.php:147
 msgid "Must-Use <span class=\"count\">(%s)</span>"
 msgid_plural "Must-Use <span class=\"count\">(%s)</span>"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/admin/bp-core-components.php:140
+#: bp-core/admin/bp-core-components.php:148
 msgid "Retired <span class=\"count\">(%s)</span>"
 msgid_plural "Retired <span class=\"count\">(%s)</span>"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/admin/bp-core-components.php:147
 #: bp-core/admin/bp-core-components.php:155
+#: bp-core/admin/bp-core-components.php:163
 msgid "Component"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:148
 #: bp-core/admin/bp-core-components.php:156
+#: bp-core/admin/bp-core-components.php:164
 msgid "Description"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:181
+#: bp-core/admin/bp-core-components.php:189
+#: bp-members/admin/bp-members-classes.php:226
+#: bp-members/admin/bp-members-classes.php:539
 msgid "Select %s"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:206
+#: bp-core/admin/bp-core-components.php:214
 msgid "No components found."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:335 bp-core/bp-core-loader.php:27
+#: bp-core/admin/bp-core-components.php:344 bp-core/bp-core-loader.php:27
 msgid "BuddyPress Core"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:336
+#: bp-core/admin/bp-core-components.php:345
 msgid "It&#8216;s what makes <del>time travel</del> BuddyPress possible!"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:339
+#: bp-core/admin/bp-core-components.php:348
 msgid "Community Members"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:340
+#: bp-core/admin/bp-core-components.php:349
 msgid "Everything in a BuddyPress community revolves around its members."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:347
+#: bp-core/admin/bp-core-components.php:356
 #: bp-templates/bp-legacy/buddypress/groups/create.php:105
 #: bp-themes/bp-default/groups/create.php:112
 msgid "Group Forums"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:348
+#: bp-core/admin/bp-core-components.php:357
 msgid "BuddyPress Forums are retired. Use %s."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:359
-msgid "Account Settings"
-msgstr ""
-
-#: bp-core/admin/bp-core-components.php:360
-msgid "Allow your users to modify their account and notification settings directly from within their profiles."
-msgstr ""
-
-#: bp-core/admin/bp-core-components.php:363 bp-friends/bp-friends-loader.php:24
+#: bp-core/admin/bp-core-components.php:372 bp-friends/bp-friends-loader.php:24
 msgid "Friend Connections"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:364
+#: bp-core/admin/bp-core-components.php:373
 msgid "Let your users make connections so they can track the activity of others and focus on the people they care about the most."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:367
+#: bp-core/admin/bp-core-components.php:376
 msgid "Private Messaging"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:368
+#: bp-core/admin/bp-core-components.php:377
 msgid "Allow your users to talk to each other directly and in private. Not just limited to one-on-one discussions, messages can be sent between any number of members."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:372
-msgid "Global, personal, and group activity streams with threaded commenting, direct posting, favoriting and @mentions, all with full RSS feed and email notification support."
+#: bp-core/admin/bp-core-components.php:381
+msgid "Global, personal, and group activity streams with threaded commenting, direct posting, favoriting, and @mentions, all with full RSS feed and email notification support."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:375 bp-groups/bp-groups-loader.php:83
+#: bp-core/admin/bp-core-components.php:388 bp-groups/bp-groups-loader.php:83
 msgid "User Groups"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:376
+#: bp-core/admin/bp-core-components.php:389
 msgid "Groups allow your users to organize themselves into specific public, private or hidden sections with separate activity streams and member listings."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:379
+#: bp-core/admin/bp-core-components.php:392
 msgid "Group Forums (Legacy)"
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:380
+#: bp-core/admin/bp-core-components.php:393
 msgid "Group forums allow for focused, bulletin-board style conversations."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:384
+#: bp-core/admin/bp-core-components.php:397
 msgid "Record activity for new posts and comments from your site."
 msgstr ""
 
-#: bp-core/admin/bp-core-components.php:391
+#: bp-core/admin/bp-core-components.php:404
 msgid "Record activity for new sites, posts, and comments across your network."
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:99
+#: bp-core/admin/bp-core-functions.php:104
 msgid "Why have all my BuddyPress menus disappeared?"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:101
+#: bp-core/admin/bp-core-functions.php:106
 msgid "Don't worry! We've moved the BuddyPress options into more convenient and easier to find locations. You're seeing this page because you are running a legacy BuddyPress plugin which has not been updated."
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:102
+#: bp-core/admin/bp-core-functions.php:107
 msgid "Components, Pages, Settings, and Forums, have been moved to <a href=\"%s\">Settings &gt; BuddyPress</a>. Profile Fields has been moved into the <a href=\"%s\">Users</a> menu."
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:216
+#: bp-core/admin/bp-core-functions.php:248
 msgid "<strong>BuddyPress is almost ready</strong>. You must <a href=\"%s\">update your permalink structure</a> to something other than the default for it to work."
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:240 bp-core/admin/bp-core-slugs.php:135
-#: bp-messages/bp-messages-template.php:558
+#: bp-core/admin/bp-core-functions.php:272 bp-core/admin/bp-core-slugs.php:135
+#: bp-members/admin/bp-members-classes.php:271
+#: bp-members/admin/bp-members-classes.php:275
+#: bp-members/admin/bp-members-classes.php:584
+#: bp-members/admin/bp-members-classes.php:586
+#: bp-messages/bp-messages-template.php:662
 #: bp-templates/bp-legacy/buddypress/members/activate.php:29
 #: bp-themes/bp-default/registration/activate.php:38
 msgid "Activate"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:245 bp-core/admin/bp-core-slugs.php:134
+#: bp-core/admin/bp-core-functions.php:277 bp-core/admin/bp-core-slugs.php:134
 #: bp-members/bp-members-adminbar.php:60
 msgid "Register"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:270
-msgid "The following active BuddyPress Components do not have associated WordPress Pages: %2$s. <a href=\"%1$s\" class=\"button-secondary\">Repair</a>"
+#: bp-core/admin/bp-core-functions.php:305
+msgid "The following active BuddyPress Components do not have associated WordPress Pages: %2$s. <a href=\"%1$s\">Repair</a>"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:292
-msgid "Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %2$s. <a href=\"%1$s\" class=\"button-secondary\">Repair</a>"
+#: bp-core/admin/bp-core-functions.php:327
+msgid "Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %2$s. <a href=\"%1$s\">Repair</a>"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:358 bp-core/admin/bp-core-slugs.php:26
+#: bp-core/admin/bp-core-functions.php:393 bp-core/admin/bp-core-slugs.php:26
 msgid "Pages"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:362
-#: bp-core/admin/bp-core-settings.php:258 bp-core/bp-core-admin.php:331
-#: bp-groups/bp-groups-loader.php:302 bp-groups/bp-groups-template.php:1468
+#: bp-core/admin/bp-core-functions.php:397
+#: bp-core/admin/bp-core-settings.php:272 bp-core/bp-core-admin.php:439
+#: bp-groups/bp-groups-loader.php:320 bp-groups/bp-groups-template.php:1512
 #: bp-settings/bp-settings-loader.php:23 bp-settings/bp-settings-loader.php:73
-#: bp-settings/bp-settings-loader.php:165
+#: bp-settings/bp-settings-loader.php:163
 msgid "Settings"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:374 bp-core/bp-core-template.php:252
-#: bp-forums/bp-forums-loader.php:109 bp-forums/bp-forums-loader.php:172
-#: bp-forums/bp-forums-loader.php:213 bp-forums/bp-forums-screens.php:188
-#: bp-forums/bp-forums-screens.php:190 bp-forums/deprecated/1.6.php:42
-#: bp-forums/deprecated/1.7.php:25 bp-forums/deprecated/1.7.php:100
+#: bp-core/admin/bp-core-functions.php:410 bp-core/bp-core-template.php:395
+#: bp-forums/bp-forums-loader.php:132 bp-forums/bp-forums-loader.php:199
+#: bp-forums/bp-forums-loader.php:240 bp-forums/bp-forums-screens.php:208
+#: bp-forums/bp-forums-screens.php:210 bp-forums/deprecated/1.6.php:42
+#: bp-forums/deprecated/1.7.php:25 bp-forums/deprecated/1.7.php:102
 msgid "Forums"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:419
+#: bp-core/admin/bp-core-functions.php:458
 msgid "<a href=\"http://codex.buddypress.org/getting-started/configure-buddypress-components/#settings-buddypress-components\">Managing Components</a>"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:437
+#: bp-core/admin/bp-core-functions.php:476
 msgid "<a href=\"http://codex.buddypress.org/getting-started/configure-buddypress-components/#settings-buddypress-pages\">Managing Pages</a>"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:456
+#: bp-core/admin/bp-core-functions.php:495
 msgid "<a href=\"http://codex.buddypress.org/getting-started/configure-buddypress-components/#settings-buddypress-settings\">Managing Settings</a>"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:475
+#: bp-core/admin/bp-core-functions.php:514
 msgid "<a href=\"http://codex.buddypress.org/getting-started/configure-buddypress-components/#users-profile-fields\">Managing Profile Fields</a>"
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:493
+#: bp-core/admin/bp-core-functions.php:532
 msgid "By default, all BuddyPress components are enabled. You can selectively disable any of the components by using the form. Your BuddyPress installation will continue to function. However, the features of the disabled components will no longer be accessible to anyone using the site."
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:497
+#: bp-core/admin/bp-core-functions.php:536
 msgid "BuddyPress Components use WordPress Pages for their root directory/archive pages. Here you can change the page associations for each active component."
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:501
+#: bp-core/admin/bp-core-functions.php:540
 msgid "Extra configuration settings."
 msgstr ""
 
-#: bp-core/admin/bp-core-functions.php:505
+#: bp-core/admin/bp-core-functions.php:544
 msgid "Your users will distinguish themselves through their profile page. Create relevant profile fields that will show on each users profile.</br></br>Note: Any fields in the first group will appear on the signup page."
 msgstr ""
 
-#: bp-core/admin/bp-core-schema.php:244
+#: bp-core/admin/bp-core-functions.php:704 bp-core/bp-core-admin.php:215
+#: bp-core/bp-core-admin.php:216 bp-core/bp-core-admin.php:236
+#: bp-core/bp-core-admin.php:290
+msgid "BuddyPress"
+msgstr ""
+
+#: bp-core/admin/bp-core-functions.php:726
+#: bp-core/admin/bp-core-functions.php:735
+msgid "Logged-In"
+msgstr ""
+
+#: bp-core/admin/bp-core-functions.php:729
+#: bp-core/admin/bp-core-functions.php:744
+msgid "Logged-Out"
+msgstr ""
+
+#: bp-core/admin/bp-core-functions.php:736
+msgid "<em>Logged-In</em> links are relative to the current user, and are not visible to visitors who are not logged in."
+msgstr ""
+
+#: bp-core/admin/bp-core-functions.php:745
+msgid "<em>Logged-Out</em> links are not visible to users who are logged in."
+msgstr ""
+
+#: bp-core/admin/bp-core-functions.php:755
+msgid "Add to Menu"
+msgstr ""
+
+#: bp-core/admin/bp-core-functions.php:900 bp-members/bp-members-actions.php:51
+#: bp-members/bp-members-admin.php:489
+msgid "User marked as spammer. Spam users are visible only to site admins."
+msgstr ""
+
+#: bp-core/admin/bp-core-functions.php:902
+msgid "User removed from spam."
+msgstr ""
+
+#: bp-core/admin/bp-core-schema.php:255
 msgctxt "First field-group name"
 msgid "General"
 msgstr ""
 
-#: bp-core/admin/bp-core-schema.php:248
+#: bp-core/admin/bp-core-schema.php:259
 msgctxt "Display name field"
 msgid "Display Name"
 msgstr ""
@@ -1340,35 +1454,39 @@ msgstr ""
 msgid "Allow activity stream commenting on blog and forum posts"
 msgstr ""
 
-#: bp-core/admin/bp-core-settings.php:153
+#: bp-core/admin/bp-core-settings.php:115
+msgid "Automatically check for new items while viewing the activity stream"
+msgstr ""
+
+#: bp-core/admin/bp-core-settings.php:167
 msgid "Enable BuddyPress to WordPress profile syncing"
 msgstr ""
 
-#: bp-core/admin/bp-core-settings.php:169
+#: bp-core/admin/bp-core-settings.php:183
 msgid "Allow registered members to upload avatars"
 msgstr ""
 
-#: bp-core/admin/bp-core-settings.php:194
+#: bp-core/admin/bp-core-settings.php:208
 msgid "Enable group creation for all users"
 msgstr ""
 
-#: bp-core/admin/bp-core-settings.php:195
+#: bp-core/admin/bp-core-settings.php:209
 msgid "Administrators can always create groups, regardless of this setting."
 msgstr ""
 
-#: bp-core/admin/bp-core-settings.php:226
+#: bp-core/admin/bp-core-settings.php:240
 msgid "Attempt to save a new config file."
 msgstr ""
 
-#: bp-core/admin/bp-core-settings.php:226
+#: bp-core/admin/bp-core-settings.php:240 bp-core/admin/bp-core-tools.php:34
 msgid "Repair"
 msgstr ""
 
-#: bp-core/admin/bp-core-settings.php:227
+#: bp-core/admin/bp-core-settings.php:241
 msgid "File does not exist"
 msgstr ""
 
-#: bp-core/admin/bp-core-settings.php:231
+#: bp-core/admin/bp-core-settings.php:245
 msgid "Absolute path to your bbPress configuration file."
 msgstr ""
 
@@ -1391,8 +1509,8 @@ msgstr ""
 #: bp-core/admin/bp-core-slugs.php:105 bp-core/admin/bp-core-slugs.php:168
 #: bp-templates/bp-legacy/buddypress/members/single/settings/capabilities.php:13
 #: bp-themes/bp-default/members/single/settings/capabilities.php:61
-#: bp-xprofile/bp-xprofile-classes.php:401
-#: bp-xprofile/bp-xprofile-classes.php:927
+#: bp-xprofile/bp-xprofile-classes.php:501
+#: bp-xprofile/bp-xprofile-classes.php:888
 msgid "Save"
 msgstr ""
 
@@ -1404,358 +1522,461 @@ msgstr ""
 msgid "Associate WordPress Pages with the following BuddyPress Registration pages."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:154 bp-core/bp-core-admin.php:155
-#: bp-core/bp-core-admin.php:163 bp-core/bp-core-admin.php:164
-msgid "Welcome to BuddyPress"
+#: bp-core/admin/bp-core-tools.php:19 bp-core/admin/bp-core-tools.php:342
+#: bp-core/admin/bp-core-tools.php:345 bp-core/bp-core-admin.php:289
+msgid "BuddyPress Tools"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:174 bp-core/bp-core-admin.php:175
-#: bp-core/bp-core-admin.php:195
-msgid "BuddyPress"
+#: bp-core/admin/bp-core-tools.php:22 bp-core/admin/bp-core-tools.php:344
+msgid "BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration."
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:23
+msgid "Use the tools below to manually recalculate these relationships."
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:25
+msgid "Some of these tools create substantial database overhead. Avoid running more than one repair job at a time."
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:31
+msgid "Data to Repair:"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:49
+msgid "Repair Items"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:105
+msgid "Count total members"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:111
+msgid "Repair user \"last activity\" data"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:120
+msgid "Count friends for each user"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:130
+msgid "Count groups for each user"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:154
+msgid "Counting the number of friends for each user&hellip; %s"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:155 bp-core/admin/bp-core-tools.php:211
+msgid "Failed!"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:184
+#: bp-core/admin/bp-core-tools.php:193 bp-core/admin/bp-core-tools.php:238
+#: bp-core/admin/bp-core-tools.php:250 bp-core/admin/bp-core-tools.php:263
+msgid "Complete!"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:210
+msgid "Counting the number of groups for each user&hellip; %s"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:247
+msgid "Counting the number of active members on the site&hellip; %s"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:261
+msgid "Determining last activity dates for each user&hellip; %s"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:320 bp-core/bp-core-admin.php:266
+#: bp-core/bp-core-admin.php:267
+msgid "Tools"
+msgstr ""
+
+#: bp-core/admin/bp-core-tools.php:345
+msgctxt "buddypress tools intro"
+msgid "Use the %s to repair these relationships."
+msgstr ""
+
+#: bp-core/bp-core-admin.php:195 bp-core/bp-core-admin.php:196
+#: bp-core/bp-core-admin.php:204 bp-core/bp-core-admin.php:205
+msgid "Welcome to BuddyPress"
+msgstr ""
+
+#: bp-core/bp-core-admin.php:225
 msgid "BuddyPress Help"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:185
+#: bp-core/bp-core-admin.php:226
 msgid "Help"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:194
+#: bp-core/bp-core-admin.php:235
 msgid "BuddyPress Components"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:203 bp-core/bp-core-admin.php:204
+#: bp-core/bp-core-admin.php:244 bp-core/bp-core-admin.php:245
 msgid "BuddyPress Pages"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:212 bp-core/bp-core-admin.php:213
+#: bp-core/bp-core-admin.php:253 bp-core/bp-core-admin.php:254
 msgid "BuddyPress Settings"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:239
+#: bp-core/bp-core-admin.php:277 bp-core/bp-core-admin.php:278
+msgid "Available Tools"
+msgstr ""
+
+#: bp-core/bp-core-admin.php:316
 msgid "Main Settings"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:242 bp-core/bp-core-admin.php:247
+#: bp-core/bp-core-admin.php:319 bp-core/bp-core-admin.php:324
 msgid "Toolbar"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:252
+#: bp-core/bp-core-admin.php:329
 msgid "Account Deletion"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:260
+#: bp-core/bp-core-admin.php:337
+#: bp-themes/bp-default/members/single/settings/profile.php:49
 msgid "Profile Settings"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:263
-msgid "Avatar Uploads"
-msgstr ""
-
-#: bp-core/bp-core-admin.php:267
+#: bp-core/bp-core-admin.php:342
 msgid "Profile Syncing"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:276
+#: bp-core/bp-core-admin.php:351
 msgid "Groups Settings"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:279
+#: bp-core/bp-core-admin.php:357
 msgid "Group Creation"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:288
+#: bp-core/bp-core-admin.php:366
 msgid "Legacy Group Forums"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:291
+#: bp-core/bp-core-admin.php:369
 msgid "bbPress Configuration"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:300
+#: bp-core/bp-core-admin.php:378
 msgid "Activity Settings"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:303
+#: bp-core/bp-core-admin.php:381
 msgid "Blog &amp; Forum Comments"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:308
+#: bp-core/bp-core-admin.php:385
+msgid "Activity auto-refresh"
+msgstr ""
+
+#: bp-core/bp-core-admin.php:390
 msgid "Akismet"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:332
-msgid "About"
+#: bp-core/bp-core-admin.php:399
+msgid "Avatar Uploads"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:383 bp-core/bp-core-admin.php:492
-msgid "Welcome to BuddyPress %s"
+#: bp-core/bp-core-admin.php:416
+msgid "About BuddyPress"
+msgstr ""
+
+#: bp-core/bp-core-admin.php:440
+msgid "About"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:386
-msgid "BuddyPress %s is our safest, fastest, most flexible version ever."
+#: bp-core/bp-core-admin.php:496 bp-core/bp-core-admin.php:645
+msgid "Welcome to BuddyPress %s"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:388
-msgid "Thank you for updating! BuddyPress %s is our safest, fastest, most flexible version ever."
+#: bp-core/bp-core-admin.php:499
+msgid "It&#8217;s a great time to use BuddyPress! With a focus on speed, admin tools, and developer enhancements, %s is our leanest and most powerful version yet."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:391 bp-core/bp-core-admin.php:494
-msgid "Version %s"
+#: bp-core/bp-core-admin.php:501
+msgid "Thanks for updating! With a focus on speed, admin tools, and developer enhancements, BuddyPress %s is our leanest and most powerful version yet."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:395 bp-core/bp-core-admin.php:498
+#: bp-core/bp-core-admin.php:509 bp-core/bp-core-admin.php:651
 msgid "What&#8217;s New"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:397 bp-core/bp-core-admin.php:500
+#: bp-core/bp-core-admin.php:511 bp-core/bp-core-admin.php:653
 msgid "Credits"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:402
+#: bp-core/bp-core-admin.php:516
 msgid "Getting Started"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:405
+#: bp-core/bp-core-admin.php:519
 msgid "Your Default Setup"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:407
+#: bp-core/bp-core-admin.php:523
 msgid "BuddyPress&#8217;s powerful features help your users connect and collaborate. To help get your community started, we&#8217;ve activated two of the most commonly used tools in BP: <strong>Extended Profiles</strong> and <strong>Activity Streams</strong>. See these components in action at the %1$s and %2$s directories, and be sure to spend a few minutes <a href=\"%3$s\">configuring user profiles</a>. Want to explore more of BP&#8217;s features? Visit the <a href=\"%4$s\">Components panel</a>."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:408 bp-core/bp-core-template.php:243
-#: bp-core/bp-core-widgets.php:113 bp-groups/bp-groups-admin.php:759
-#: bp-groups/bp-groups-template.php:1476 bp-members/bp-members-loader.php:24
-#: bp-members/bp-members-screens.php:355
+#: bp-core/bp-core-admin.php:524 bp-core/bp-core-template.php:386
+#: bp-core/bp-core-widgets.php:276 bp-groups/bp-groups-admin.php:781
+#: bp-groups/bp-groups-template.php:1520 bp-members/bp-members-loader.php:24
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:231
 #: bp-themes/bp-default/groups/single/admin.php:231
 msgid "Members"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:414
+#: bp-core/bp-core-admin.php:532
+msgid "BuddyPress&#8217;s powerful features help your users connect and collaborate. Want to explore BP&#8217;s features? Visit the <a href=\"%s\">Components panel</a>."
+msgstr ""
+
+#: bp-core/bp-core-admin.php:538
 msgid "Community and Support"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:415
+#: bp-core/bp-core-admin.php:539
 msgid "Looking for help? The <a href=\"http://codex.buddypress.org/\">BuddyPress Codex</a> has you covered, with dozens of user-contributed guides on how to configure and use your BP site. Can&#8217;t find what you need? Stop by <a href=\"http://buddypress.org/support/\">our support forums</a>, where a vibrant community of BuddyPress users and developers is waiting to share tips, show off their sites, talk about the future of BuddyPress, and much more."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:421
-msgid "Improved Theme Integration"
+#: bp-core/bp-core-admin.php:546
+msgid "Performance Improvements"
+msgstr ""
+
+#: bp-core/bp-core-admin.php:548
+msgid "Whether your community has tens of members or tens of thousands, we think the performance improvements in BuddyPress 2.0 will knock your socks off. We&#8217;ve slashed our memory footprint and query overhead across the board, with a special focus on the Activity and Members components."
+msgstr ""
+
+#: bp-core/bp-core-admin.php:554
+msgid "New Administrative Tools"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:424
-msgid "Hey, Good Lookin&#8217;"
+#: bp-core/bp-core-admin.php:558
+msgid "Extended Profiles in Admin"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:425
-msgid "We&#8217;ve streamlined our stylesheets, so that BuddyPress content looks more at home in your theme. And theme developers will love BP&#8217;s new hierarchies that make it easy to override specific top-level templates, stylesheets, and JavaScript files."
+#: bp-core/bp-core-admin.php:559
+msgid "Site administrators can edit members&#8217; xProfile data at Dashboard > Users > Extended Profiles."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:430
-msgid "Better Group Member Management"
+#: bp-core/bp-core-admin.php:564
+msgid "Registration Management"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:433
-msgid "<em>Add</em>, <em>Remove</em>, and More, in a Snap"
+#: bp-core/bp-core-admin.php:565
+msgid "Perform common tasks with pending signups - including resending activation emails and manually activating accounts - on the new Pending tab of Dashboard > Users."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:436
-msgid "Groups administration panel"
+#: bp-core/bp-core-admin.php:572
+msgid "BuddyPress Repair Tools"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:443
-msgid "The Manage Members section of the %s has been rewritten, to make it easier to handle groups with many members. We&#8217;ve also made the interface nicer to use, to ensure that you don&#8217;t make changes and then forget to save them."
+#: bp-core/bp-core-admin.php:573
+msgid "Dashboard > Tools > BuddyPress contains a number of tools for correcting data that occasionally gets out of sync on BP installs."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:450
-msgid "Under the Hood"
+#: bp-core/bp-core-admin.php:578
+msgid "Mark Spammers in Admin"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:454
-msgid "Superpowered Group Extensions"
+#: bp-core/bp-core-admin.php:579
+msgid "Admins on non-Multisite installations can now perform spam actions from Dashboard > Users > All Users."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:455
-msgid "<code>BP_Group_Extension</code> has been overhauled, making it easier than ever before to add custom functionality to groups."
+#: bp-core/bp-core-admin.php:589
+msgid "A More Dynamic Activity Stream"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:457
-msgid "Filter Groups or Activity by Metadata"
+#: bp-core/bp-core-admin.php:592
+msgid "Spend a lot of time viewing the activity stream? BuddyPress 2.0 automatically lets you know when new items are waiting to be loaded."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:458
-msgid "<code>bp_has_groups()</code> and <code>bp_has_activities()</code> now accept a <code>meta_query</code> paramater, for more powerful directory queries."
+#: bp-core/bp-core-admin.php:594
+msgid "The activity stream is better integrated with blog posts, too. Comment on a blog post, and an activity item is posted. Comment on a blog-related activity item, and a blog comment is posted. No more worrying about fractured conversations."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:462
-msgid "Feed Me, Seymour"
+#: bp-core/bp-core-admin.php:596
+msgid "We&#8217;ve also reworked the way that phrases like \"Boone posted an update\" are handled, so that they&#8217;re always up-to-date and always translatable."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:463
-msgid "The new <code>BP_Activity_Feed</code> class centralizes BP&#8217;s RSS logic, making our feeds more standards-compliant, and giving developers more tools for building custom feeds."
+#: bp-core/bp-core-admin.php:608
+msgid "Developer Tools"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:465
-msgid "Disable @-Mentions"
+#: bp-core/bp-core-admin.php:610
+msgid "BuddyPress 2.0 is full of new and improved tools for the theme and plugin developer. A few highlights:"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:466
-msgid "Not using @-mentions? Disable them with <code>add_filter( 'bp_activity_do_mentions', '__return_false' );</code>"
+#: bp-core/bp-core-admin.php:612
+msgid "The <code>BP_XProfile_Field_Type</code> class makes it a breeze to create new xProfile field types with custom display callbacks, validation, and more."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:471 bp-core/bp-core-admin.php:601
+#: bp-core/bp-core-admin.php:613
+msgid "Major improvements have taken place with respect to object caching throughout BuddyPress. If you use Memcached, APC, or some other persistent object caching backend on your BuddyPress site, you should notice huge performance boosts."
+msgstr ""
+
+#: bp-core/bp-core-admin.php:614
+msgid "Our internal metadata libraries have been rewritten to use WP&#8217;s <code>add_metadata()</code>, <code>update_metadata()</code>, and so on. This means greater consistency and parity between the components when storing and retrieving BuddyPress metadata."
+msgstr ""
+
+#: bp-core/bp-core-admin.php:615
+msgid "<a href=\"%s\">&hellip;and lots more!</a>"
+msgstr ""
+
+#: bp-core/bp-core-admin.php:623 bp-core/bp-core-admin.php:757
 msgid "Go to the BuddyPress Settings page"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:493
-msgid "Thank you for updating to the latest version! BuddyPress %s is ready to make your community a safer, faster, and better looking place to hang out!"
+#: bp-core/bp-core-admin.php:646
+msgid "BuddyPress %s is our first version with a new component in over two years. Not only that, there are plenty of new features, enhancements, and bug fixes."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:504
+#: bp-core/bp-core-admin.php:657
 msgid "BuddyPress is created by a worldwide network of friendly folks."
 msgstr ""
 
-#: bp-core/bp-core-admin.php:506
+#: bp-core/bp-core-admin.php:659
 msgid "Project Leaders"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:511
-msgid "Founding Developer"
-msgstr ""
-
-#: bp-core/bp-core-admin.php:516
+#: bp-core/bp-core-admin.php:664
 msgid "Project Lead"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:521 bp-core/bp-core-admin.php:526
+#: bp-core/bp-core-admin.php:669 bp-core/bp-core-admin.php:674
 msgid "Lead Developer"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:530
-msgid "Core Developers"
+#: bp-core/bp-core-admin.php:678
+msgid "Core Team"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:538
-msgid "Recent Rockstars"
+#: bp-core/bp-core-admin.php:683 bp-core/bp-core-admin.php:688
+msgid "Core Developer"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:543
-msgid "Design Officer"
+#: bp-core/bp-core-admin.php:693
+msgid "Navigator"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:548
-msgid "Support Officer"
+#: bp-core/bp-core-admin.php:697
+msgid "Recent Rockstars"
 msgstr ""
 
-#: bp-core/bp-core-admin.php:552
-msgid "Core Contributors to BuddyPress 1.8"
+#: bp-core/bp-core-admin.php:709
+msgid "Contributors to BuddyPress 2.0"
 msgstr ""
 
-#: bp-core/bp-core-adminbar.php:35 bp-core/bp-core-buddybar.php:495
+#: bp-core/bp-core-adminbar.php:36 bp-core/bp-core-buddybar.php:571
 msgid "My Account"
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:231
+#: bp-core/bp-core-avatars.php:303
 msgid "Avatar Image"
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:499
+#: bp-core/bp-core-avatars.php:578
 msgid "The image was uploaded successfully"
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:500 bp-core/bp-core-avatars.php:501
+#: bp-core/bp-core-avatars.php:579 bp-core/bp-core-avatars.php:580
 msgid "The image exceeds the maximum allowed file size of: "
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:502
+#: bp-core/bp-core-avatars.php:581
 msgid "The uploaded file was only partially uploaded."
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:503
+#: bp-core/bp-core-avatars.php:582
 msgid "The image was not uploaded."
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:504
+#: bp-core/bp-core-avatars.php:583
 msgid "Missing a temporary folder."
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:508
+#: bp-core/bp-core-avatars.php:587
 msgid "Your upload failed, please try again. Error was: %s"
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:513
+#: bp-core/bp-core-avatars.php:592
 msgid "The file you uploaded is too big. Please upload a file under %s"
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:518
+#: bp-core/bp-core-avatars.php:597
 msgid "Please upload only JPG, GIF or PNG photos."
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:535 bp-core/bp-core-avatars.php:572
+#: bp-core/bp-core-avatars.php:614 bp-core/bp-core-avatars.php:651
 msgid "Upload Failed! Error was: %s"
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:590
+#: bp-core/bp-core-avatars.php:669
 msgid "Upload failed! Error was: %s"
 msgstr ""
 
-#: bp-core/bp-core-avatars.php:733 bp-core/bp-core-classes.php:771
-#: bp-core/bp-core-classes.php:772 bp-core/bp-core-classes.php:773
-#: bp-core/bp-core-template.php:98 bp-core/bp-core-template.php:107
+#: bp-core/bp-core-avatars.php:843 bp-core/bp-core-classes.php:813
+#: bp-core/bp-core-classes.php:814 bp-core/bp-core-classes.php:815
+#: bp-core/bp-core-template.php:160 bp-core/bp-core-template.php:176
+#: bp-groups/bp-groups-template.php:3362 bp-groups/bp-groups-template.php:3363
+#: bp-groups/bp-groups-template.php:3364
 msgid "Avatar of %s"
 msgstr ""
 
-#: bp-core/bp-core-buddybar.php:302
+#: bp-core/bp-core-buddybar.php:356
 msgid "You do not have access to this page."
 msgstr ""
 
-#: bp-core/bp-core-buddybar.php:479 bp-themes/bp-default/sidebar.php:52
+#: bp-core/bp-core-buddybar.php:552 bp-core/bp-core-functions.php:1806
+#: bp-core/bp-core-widgets.php:90 bp-themes/bp-default/sidebar.php:52
 msgid "Log In"
 msgstr ""
 
-#: bp-core/bp-core-buddybar.php:483
+#: bp-core/bp-core-buddybar.php:556
 msgid "Sign Up"
 msgstr ""
 
-#: bp-core/bp-core-buddybar.php:537 bp-core/deprecated/1.5.php:307
-#: bp-members/bp-members-template.php:774 bp-themes/bp-default/sidebar.php:18
+#: bp-core/bp-core-buddybar.php:613 bp-core/bp-core-functions.php:1739
+#: bp-core/bp-core-widgets.php:72 bp-core/deprecated/1.5.php:307
+#: bp-members/bp-members-template.php:835 bp-themes/bp-default/sidebar.php:18
 msgid "Log Out"
 msgstr ""
 
-#: bp-core/bp-core-buddybar.php:566 bp-groups/bp-groups-admin.php:1335
+#: bp-core/bp-core-buddybar.php:645 bp-groups/bp-groups-admin.php:1393
 msgid "Visit"
 msgstr ""
 
-#: bp-core/bp-core-buddybar.php:568
+#: bp-core/bp-core-buddybar.php:647
 msgid "Random Member"
 msgstr ""
 
-#: bp-core/bp-core-buddybar.php:572
+#: bp-core/bp-core-buddybar.php:651
 msgid "Random Group"
 msgstr ""
 
-#: bp-core/bp-core-buddybar.php:578
+#: bp-core/bp-core-buddybar.php:657
 msgid "Random Site"
 msgstr ""
 
-#: bp-core/bp-core-caps.php:248 bp-core/bp-core-caps.php:261
-#: bp-core/bp-core-caps.php:276 bp-core/bp-core-caps.php:287
+#: bp-core/bp-core-caps.php:256 bp-core/bp-core-caps.php:268
+#: bp-core/bp-core-caps.php:282 bp-core/bp-core-caps.php:292
 msgid "Special community roles no longer exist. Use mapped capabilities instead"
 msgstr ""
 
-#: bp-core/bp-core-catchuri.php:280
+#: bp-core/bp-core-catchuri.php:276
 msgid "This user has been marked as a spammer. Only site admins can view this profile."
 msgstr ""
 
-#: bp-core/bp-core-catchuri.php:466 bp-core/bp-core-catchuri.php:525
+#: bp-core/bp-core-catchuri.php:471 bp-core/bp-core-catchuri.php:531
 msgid "You must log in to access the page you requested."
 msgstr ""
 
-#: bp-core/bp-core-classes.php:788
+#: bp-core/bp-core-classes.php:830 bp-groups/bp-groups-template.php:3372
 msgid "%d group"
 msgid_plural "%d groups"
 msgstr[0] ""
@@ -1765,11 +1986,11 @@ msgstr[1] ""
 msgid "The current user is being initialized without using $wp->init()."
 msgstr ""
 
-#: bp-core/bp-core-filters.php:216 bp-core/bp-core-filters.php:240
+#: bp-core/bp-core-filters.php:261 bp-core/bp-core-filters.php:291
 msgid "[User Set]"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:258
+#: bp-core/bp-core-filters.php:320
 msgid ""
 "Thanks for registering! To complete the activation of your account and blog, please click the following link:\n"
 "\n"
@@ -1782,11 +2003,11 @@ msgid ""
 "%2$s"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:259
+#: bp-core/bp-core-filters.php:321
 msgid "Activate %s"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:286 bp-members/bp-members-functions.php:1390
+#: bp-core/bp-core-filters.php:359 bp-members/bp-members-functions.php:1705
 msgid ""
 "Thanks for registering! To complete the activation of your account please click the following link:\n"
 "\n"
@@ -1794,157 +2015,168 @@ msgid ""
 "\n"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:287 bp-members/bp-members-functions.php:1391
+#: bp-core/bp-core-filters.php:360 bp-members/bp-members-functions.php:1706
 msgid "Activate Your Account"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:343
+#: bp-core/bp-core-filters.php:427
 msgctxt "Construct the page title. 1 = user name, 2 = component name, 3 = seperator"
 msgid "%1$s %3$s %2$s"
 msgstr ""
 
 #. translators: "group name | group nav section name"
 
-#: bp-core/bp-core-filters.php:349
+#: bp-core/bp-core-filters.php:433
 msgid "%1$s | %2$s"
 msgstr ""
 
 #. translators: "component item name | component nav section name | root
 #. component name"
 
-#: bp-core/bp-core-filters.php:354
+#: bp-core/bp-core-filters.php:438
 msgid "%1$s | %2$s | %3$s"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:359 bp-core/bp-core-filters.php:361
-msgid "%s Directory"
+#: bp-core/bp-core-filters.php:447
+msgctxt "component directory title"
+msgid "Directory"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:366 bp-members/bp-members-screens.php:512
+#: bp-core/bp-core-filters.php:454 bp-members/bp-members-screens.php:519
 #: bp-themes/bp-default/registration/register.php:23
 msgid "Create an Account"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:370 bp-members/bp-members-screens.php:520
+#: bp-core/bp-core-filters.php:458 bp-members/bp-members-screens.php:527
 #: bp-themes/bp-default/registration/activate.php:13
 msgid "Activate your Account"
 msgstr ""
 
-#: bp-core/bp-core-filters.php:374 bp-groups/bp-groups-loader.php:554
-#: bp-groups/bp-groups-screens.php:1027 bp-groups/bp-groups-screens.php:1088
+#: bp-core/bp-core-filters.php:462 bp-groups/bp-groups-loader.php:577
+#: bp-groups/bp-groups-template.php:1911 bp-groups/bp-groups-template.php:1912
 #: bp-themes/bp-default/groups/create.php:18
 #: bp-themes/bp-default/groups/index.php:21
 msgid "Create a Group"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:322
+#: bp-core/bp-core-functions.php:447
 msgctxt "Page title for the Activity directory."
 msgid "Activity"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:323
+#: bp-core/bp-core-functions.php:448
 msgctxt "Page title for the Groups directory."
 msgid "Groups"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:324
+#: bp-core/bp-core-functions.php:449
 msgctxt "Page title for the Sites directory."
 msgid "Sites"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:325
+#: bp-core/bp-core-functions.php:450
 msgctxt "Page title for the user account activation screen."
 msgid "Activate"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:326
+#: bp-core/bp-core-functions.php:451
 msgctxt "Page title for the Members directory."
 msgid "Members"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:327
+#: bp-core/bp-core-functions.php:452
 msgctxt "Page title for the user registration screen."
 msgid "Register"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:592
+#: bp-core/bp-core-functions.php:777
 msgid "sometime"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:593
+#: bp-core/bp-core-functions.php:778
 msgid "right now"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:594
+#: bp-core/bp-core-functions.php:779
 msgid "%s ago"
 msgstr ""
 
-#: bp-core/bp-core-functions.php:655
+#: bp-core/bp-core-functions.php:840
 msgid "%s year"
 msgid_plural "%s years"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/bp-core-functions.php:658 bp-core/bp-core-functions.php:692
+#: bp-core/bp-core-functions.php:843 bp-core/bp-core-functions.php:877
 msgid "%s month"
 msgid_plural "%s months"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/bp-core-functions.php:661 bp-core/bp-core-functions.php:695
+#: bp-core/bp-core-functions.php:846 bp-core/bp-core-functions.php:880
 msgid "%s week"
 msgid_plural "%s weeks"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/bp-core-functions.php:664 bp-core/bp-core-functions.php:698
+#: bp-core/bp-core-functions.php:849 bp-core/bp-core-functions.php:883
 msgid "%s day"
 msgid_plural "%s days"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/bp-core-functions.php:667 bp-core/bp-core-functions.php:701
+#: bp-core/bp-core-functions.php:852 bp-core/bp-core-functions.php:886
 msgid "%s hour"
 msgid_plural "%s hours"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/bp-core-functions.php:670 bp-core/bp-core-functions.php:704
+#: bp-core/bp-core-functions.php:855 bp-core/bp-core-functions.php:889
 msgid "%s minute"
 msgid_plural "%s minutes"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/bp-core-functions.php:673 bp-core/bp-core-functions.php:707
+#: bp-core/bp-core-functions.php:858 bp-core/bp-core-functions.php:892
 msgid "%s second"
 msgid_plural "%s seconds"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-core/bp-core-functions.php:688
+#: bp-core/bp-core-functions.php:873
 msgctxt "Separator in time since"
 msgid ","
 msgstr ""
 
-#: bp-core/bp-core-functions.php:866
+#: bp-core/bp-core-functions.php:1065
 msgid "Not recently active"
 msgstr ""
 
-#: bp-core/bp-core-loader.php:215 bp-members/bp-members-loader.php:158
-#: bp-xprofile/bp-xprofile-loader.php:154
-#: bp-xprofile/bp-xprofile-loader.php:229
+#: bp-core/bp-core-loader.php:233 bp-members/bp-members-admin.php:329
+#: bp-members/bp-members-loader.php:184 bp-xprofile/bp-xprofile-loader.php:162
+#: bp-xprofile/bp-xprofile-loader.php:223
+#: bp-xprofile/bp-xprofile-loader.php:255
+#: bp-xprofile/bp-xprofile-loader.php:295
 msgid "Profile"
 msgstr ""
 
-#: bp-core/bp-core-template.php:65
+#: bp-core/bp-core-template.php:81
 msgid "Options"
 msgstr ""
 
-#: bp-core/bp-core-template.php:191
+#: bp-core/bp-core-template.php:105
+msgid "%s Directory"
+msgstr ""
+
+#: bp-core/bp-core-template.php:304
 msgid "%1$s at %2$s"
 msgstr ""
 
-#: bp-core/bp-core-template.php:254
+#: bp-core/bp-core-template.php:392
+msgid "Blogs"
+msgstr ""
+
+#: bp-core/bp-core-template.php:397
 #: bp-templates/bp-legacy/buddypress/activity/index.php:83
 #: bp-templates/bp-legacy/buddypress/forums/forums-loop.php:40
 #: bp-templates/bp-legacy/buddypress/members/single/activity.php:27
@@ -1954,57 +2186,54 @@ msgstr ""
 msgid "Posts"
 msgstr ""
 
-#: bp-core/bp-core-template.php:257
+#: bp-core/bp-core-template.php:400
 msgid "Search these:"
 msgstr ""
 
-#: bp-core/bp-core-template.php:285
+#: bp-core/bp-core-template.php:438
 msgid "Search anything..."
 msgstr ""
 
-#: bp-core/bp-core-template.php:379
+#: bp-core/bp-core-template.php:540
 msgid " [&hellip;]"
 msgstr ""
 
-#: bp-core/bp-core-template.php:557
+#: bp-core/bp-core-template.php:761
 msgid "Community"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:19
-msgid "A dynamic list of recently active, popular, and newest members"
+#: bp-core/bp-core-widgets.php:36
+msgctxt "Title of the login widget"
+msgid "(BuddyPress) Log In"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:22
-msgctxt "widget name"
-msgid "(BuddyPress) Members"
+#: bp-core/bp-core-widgets.php:38
+msgid "Show a Log In form to logged-out visitors, and a Log Out link to those who are logged in."
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:49 bp-core/bp-core-widgets.php:135
-#: bp-core/deprecated/1.6.php:129 bp-core/deprecated/1.6.php:152
-#: bp-groups/bp-groups-widgets.php:60 bp-groups/bp-groups-widgets.php:141
-#: bp-templates/bp-legacy/buddypress/blogs/index.php:39
-#: bp-templates/bp-legacy/buddypress/members/single/blogs.php:22
-#: bp-themes/bp-default/blogs/index.php:56
-#: bp-themes/bp-default/members/single/blogs.php:22
-msgid "Newest"
+#: bp-core/bp-core-widgets.php:82 bp-members/admin/bp-members-classes.php:127
+#: bp-members/admin/bp-members-classes.php:445
+#: bp-templates/bp-legacy/buddypress/members/register.php:32
+#: bp-themes/bp-default/registration/register.php:37
+#: bp-themes/bp-default/sidebar.php:44
+msgid "Username"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:50 bp-core/bp-core-widgets.php:136
-#: bp-groups/bp-groups-widgets.php:61 bp-groups/bp-groups-widgets.php:142
-msgid "Active"
+#: bp-core/bp-core-widgets.php:85 bp-themes/bp-default/sidebar.php:47
+msgid "Password"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:54 bp-core/bp-core-widgets.php:137
-#: bp-groups/bp-groups-widgets.php:62 bp-groups/bp-groups-widgets.php:143
-msgid "Popular"
+#: bp-core/bp-core-widgets.php:88 bp-themes/bp-default/sidebar.php:50
+msgid "Remember Me"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:91
-msgid "No one has signed up yet!"
+#: bp-core/bp-core-widgets.php:94
+msgid "<a href=\"%s\" title=\"Register for a new account\">Register</a>"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:126 bp-core/bp-core-widgets.php:208
-#: bp-core/bp-core-widgets.php:277 bp-groups/bp-groups-widgets.php:132
+#: bp-core/bp-core-widgets.php:133 bp-core/bp-core-widgets.php:289
+#: bp-core/bp-core-widgets.php:405 bp-core/bp-core-widgets.php:508
+#: bp-groups/bp-groups-widgets.php:137 bp-messages/bp-messages-widgets.php:110
 #: bp-templates/bp-legacy/buddypress/forums/index.php:86
 #: bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php:47
 #: bp-templates/bp-legacy/buddypress/groups/single/forum.php:75
@@ -2014,53 +2243,95 @@ msgstr ""
 msgid "Title:"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:128
+#: bp-core/bp-core-widgets.php:151
+msgid "A dynamic list of recently active, popular, and newest members"
+msgstr ""
+
+#: bp-core/bp-core-widgets.php:154
+msgctxt "widget name"
+msgid "(BuddyPress) Members"
+msgstr ""
+
+#: bp-core/bp-core-widgets.php:200 bp-core/bp-core-widgets.php:298
+#: bp-core/deprecated/1.6.php:129 bp-core/deprecated/1.6.php:152
+#: bp-friends/bp-friends-widgets.php:91 bp-friends/bp-friends-widgets.php:179
+#: bp-groups/bp-groups-template.php:2417 bp-groups/bp-groups-widgets.php:65
+#: bp-groups/bp-groups-widgets.php:146
+#: bp-templates/bp-legacy/buddypress/blogs/index.php:39
+#: bp-templates/bp-legacy/buddypress/members/single/blogs.php:22
+#: bp-themes/bp-default/blogs/index.php:56
+#: bp-themes/bp-default/members/single/blogs.php:22
+msgid "Newest"
+msgstr ""
+
+#: bp-core/bp-core-widgets.php:201 bp-core/bp-core-widgets.php:299
+#: bp-friends/bp-friends-widgets.php:92 bp-friends/bp-friends-widgets.php:180
+#: bp-groups/bp-groups-widgets.php:66 bp-groups/bp-groups-widgets.php:147
+#: bp-members/bp-members-admin.php:642
+msgid "Active"
+msgstr ""
+
+#: bp-core/bp-core-widgets.php:205 bp-core/bp-core-widgets.php:300
+#: bp-friends/bp-friends-widgets.php:93 bp-friends/bp-friends-widgets.php:181
+#: bp-groups/bp-groups-widgets.php:67 bp-groups/bp-groups-widgets.php:148
+msgid "Popular"
+msgstr ""
+
+#: bp-core/bp-core-widgets.php:242
+msgid "No one has signed up yet!"
+msgstr ""
+
+#: bp-core/bp-core-widgets.php:291 bp-friends/bp-friends-widgets.php:172
 msgid "Link widget title to Members directory"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:130
+#: bp-core/bp-core-widgets.php:293
 msgid "Max members to show:"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:133
+#: bp-core/bp-core-widgets.php:296
 msgid "Default members to show:"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:152
+#: bp-core/bp-core-widgets.php:318
 msgid "Avatars of users who are currently online"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:155
+#: bp-core/bp-core-widgets.php:321
 msgctxt "widget name"
 msgid "(BuddyPress) Who's Online"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:180
+#: bp-core/bp-core-widgets.php:365
 msgid "There are no users currently online"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:199
+#: bp-core/bp-core-widgets.php:396
 msgid "Who's Online"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:210 bp-core/bp-core-widgets.php:279
+#: bp-core/bp-core-widgets.php:407 bp-core/bp-core-widgets.php:510
 msgid "Max Members to show:"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:221
+#: bp-core/bp-core-widgets.php:421
 msgid "Avatars of recently active members"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:224
+#: bp-core/bp-core-widgets.php:424
 msgctxt "widget name"
 msgid "(BuddyPress) Recently Active Members"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:249
+#: bp-core/bp-core-widgets.php:468
 msgid "There are no recently active members"
 msgstr ""
 
-#: bp-core/bp-core-widgets.php:331
+#: bp-core/bp-core-widgets.php:499
+msgid "Recently Active Members"
+msgstr ""
+
+#: bp-core/bp-core-widgets.php:572 bp-friends/bp-friends-widgets.php:245
 msgid "There were no members found, please try another filter."
 msgstr ""
 
@@ -2069,11 +2340,12 @@ msgstr ""
 #: bp-templates/bp-legacy/buddypress/members/single/profile/profile-wp.php:8
 #: bp-themes/bp-default/activity/post-form.php:45
 #: bp-themes/bp-default/members/single/profile/profile-wp.php:8
-#: bp-xprofile/bp-xprofile-loader.php:272
+#: bp-xprofile/bp-xprofile-loader.php:312
 msgid "My Profile"
 msgstr ""
 
-#: bp-core/deprecated/1.5.php:149
+#: bp-core/deprecated/1.5.php:149 bp-members/admin/bp-members-classes.php:128
+#: bp-members/admin/bp-members-classes.php:446
 #: bp-templates/bp-legacy/buddypress/members/single/profile/profile-wp.php:15
 #: bp-themes/bp-default/functions.php:643
 #: bp-themes/bp-default/members/single/profile/profile-wp.php:15
@@ -2116,146 +2388,150 @@ msgid "%1$s mentioned you in the group \"%2$s\""
 msgstr ""
 
 #: bp-core/deprecated/1.6.php:128 bp-core/deprecated/1.6.php:149
-#: bp-groups/bp-groups-template.php:2518 bp-groups/bp-groups-template.php:2540
+#: bp-groups/bp-groups-template.php:2788 bp-groups/bp-groups-template.php:2810
 msgid "Recently Active"
 msgstr ""
 
 #: bp-core/deprecated/1.6.php:130 bp-core/deprecated/1.6.php:155
-#: bp-groups/bp-groups-template.php:2523 bp-groups/bp-groups-template.php:2555
+#: bp-groups/bp-groups-template.php:2793 bp-groups/bp-groups-template.php:2825
 msgid "Alphabetically"
 msgstr ""
 
-#: bp-forums/bp-forums-loader.php:25
+#: bp-forums/bp-forums-loader.php:28
 msgid "Discussion Forums"
 msgstr ""
 
-#: bp-forums/bp-forums-loader.php:60
+#: bp-forums/bp-forums-loader.php:70
 msgid "Search Forums..."
 msgstr ""
 
-#: bp-forums/bp-forums-loader.php:131 bp-forums/bp-forums-loader.php:180
+#: bp-forums/bp-forums-loader.php:154 bp-forums/bp-forums-loader.php:207
 msgid "Topics Started"
 msgstr ""
 
-#: bp-forums/bp-forums-loader.php:142
+#: bp-forums/bp-forums-loader.php:165
 msgid "Replied To"
 msgstr ""
 
-#: bp-forums/bp-forums-loader.php:188
+#: bp-forums/bp-forums-loader.php:215
 msgid "Replies"
 msgstr ""
 
-#: bp-forums/bp-forums-loader.php:196
+#: bp-forums/bp-forums-loader.php:223
 msgid "Favorite Topics"
 msgstr ""
 
-#: bp-forums/bp-forums-screens.php:15 bp-forums/bp-forums-screens.php:162
+#: bp-forums/bp-forums-screens.php:25 bp-forums/bp-forums-screens.php:182
 msgid "The forums component has not been set up yet."
 msgstr ""
 
-#: bp-forums/bp-forums-screens.php:38 bp-groups/bp-groups-screens.php:381
+#: bp-forums/bp-forums-screens.php:48 bp-groups/bp-groups-screens.php:371
 msgid "Please provide a title for your forum topic."
 msgstr ""
 
-#: bp-forums/bp-forums-screens.php:40 bp-groups/bp-groups-screens.php:383
+#: bp-forums/bp-forums-screens.php:50 bp-groups/bp-groups-screens.php:373
 msgid "Forum posts cannot be empty. Please enter some text."
 msgstr ""
 
-#: bp-forums/bp-forums-screens.php:47 bp-groups/bp-groups-screens.php:395
+#: bp-forums/bp-forums-screens.php:57 bp-groups/bp-groups-screens.php:385
 msgid "There was an error when creating the topic"
 msgstr ""
 
-#: bp-forums/bp-forums-screens.php:50 bp-groups/bp-groups-screens.php:398
+#: bp-forums/bp-forums-screens.php:60 bp-groups/bp-groups-screens.php:388
 msgid "The topic was created successfully"
 msgstr ""
 
-#: bp-forums/bp-forums-screens.php:58 bp-forums/bp-forums-screens.php:63
+#: bp-forums/bp-forums-screens.php:68 bp-forums/bp-forums-screens.php:73
 msgid "Please pick the group forum where you would like to post this topic."
 msgstr ""
 
-#: bp-forums/bp-forums-screens.php:188 bp-groups/bp-groups-template.php:1712
-#: bp-groups/bp-groups-template.php:1713
+#: bp-forums/bp-forums-screens.php:208 bp-groups/bp-groups-template.php:1756
+#: bp-groups/bp-groups-template.php:1757
 #: bp-templates/bp-legacy/buddypress/groups/single/forum.php:19
 #: bp-themes/bp-default/forums/index.php:23
 #: bp-themes/bp-default/groups/single/forum.php:19
 msgid "New Topic"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:188 bp-forums/bp-forums-template.php:404
+#: bp-forums/bp-forums-template.php:296 bp-forums/bp-forums-template.php:568
 msgctxt "Forum topic pagination previous text"
 msgid "&larr;"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:189 bp-forums/bp-forums-template.php:405
+#: bp-forums/bp-forums-template.php:297 bp-forums/bp-forums-template.php:569
 msgctxt "Forum topic pagination next text"
 msgid "&rarr;"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:505 bp-forums/bp-forums-template.php:567
-#: bp-forums/bp-forums-template.php:1216
-#: bp-messages/bp-messages-classes.php:269
-#: bp-messages/bp-messages-template.php:843
-#: bp-messages/bp-messages-template.php:904
+#: bp-forums/bp-forums-template.php:756 bp-forums/bp-forums-template.php:870
+#: bp-forums/bp-forums-template.php:2014
+#: bp-messages/bp-messages-classes.php:474
+#: bp-messages/bp-messages-template.php:945
+#: bp-messages/bp-messages-template.php:1027
 msgid "Deleted User"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:585
+#: bp-forums/bp-forums-template.php:916
 msgid "Group logo for %s"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:683 bp-groups/bp-groups-template.php:1035
+#: bp-forums/bp-forums-template.php:1103 bp-groups/bp-groups-template.php:1079
 msgid "%d post"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:685 bp-groups/bp-groups-template.php:1037
+#: bp-forums/bp-forums-template.php:1105 bp-groups/bp-groups-template.php:1081
 msgid "%d posts"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:791
+#: bp-forums/bp-forums-template.php:1291
 msgid "Edit Topic"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:795
+#: bp-forums/bp-forums-template.php:1295
 msgid "Sticky Topic"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:797
+#: bp-forums/bp-forums-template.php:1297
 msgid "Un-stick Topic"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:800
+#: bp-forums/bp-forums-template.php:1300
 msgid "Open Topic"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:802
+#: bp-forums/bp-forums-template.php:1302
 msgid "Close Topic"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:804
+#: bp-forums/bp-forums-template.php:1304
 msgid "Delete Topic"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:959
+#: bp-forums/bp-forums-template.php:1525
 msgid " matching tag \"%s\""
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:961
-msgid "Viewing topic %s to %s (of %s total topics%s)"
-msgstr ""
+#: bp-forums/bp-forums-template.php:1527
+msgid "Viewing topic %s to %s (of %d topic%s)"
+msgid_plural "Viewing topic %s to %s (of %d total topics%s)"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-forums/bp-forums-template.php:1052
+#: bp-forums/bp-forums-template.php:1736
 msgctxt "Forum thread pagination previous text"
 msgid "&larr;"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:1053
+#: bp-forums/bp-forums-template.php:1737
 msgctxt "Forum thread pagination next text"
 msgid "&rarr;"
 msgstr ""
 
-#: bp-forums/bp-forums-template.php:1301
-msgid "Viewing post %1$s to %2$s (%3$s total posts)"
-msgstr ""
+#: bp-forums/bp-forums-template.php:2166
+msgid "Viewing post %1$s to %2$s (%3$s post)"
+msgid_plural "Viewing post %1$s to %2$s (%3$s total posts)"
+msgstr[0] ""
+msgstr[1] ""
 
 #: bp-forums/deprecated/1.6.php:31 bp-forums/deprecated/1.6.php:133
 msgid "Configure bbPress"
@@ -2407,84 +2683,69 @@ msgstr ""
 msgid "Use Existing Installation"
 msgstr ""
 
-#: bp-friends/bp-friends-actions.php:35
+#: bp-friends/bp-friends-actions.php:38
 msgid "Friendship could not be requested."
 msgstr ""
 
-#: bp-friends/bp-friends-actions.php:37
+#: bp-friends/bp-friends-actions.php:40
 msgid "Friendship requested"
 msgstr ""
 
-#: bp-friends/bp-friends-actions.php:41
+#: bp-friends/bp-friends-actions.php:44
 msgid "You are already friends with this user"
 msgstr ""
 
-#: bp-friends/bp-friends-actions.php:43
+#: bp-friends/bp-friends-actions.php:46
 msgid "You already have a pending friendship request with this user"
 msgstr ""
 
-#: bp-friends/bp-friends-actions.php:70
-#: bp-templates/bp-legacy/buddypress-functions.php:955
-#: bp-themes/bp-default/_inc/ajax.php:617
+#: bp-friends/bp-friends-actions.php:76
+#: bp-templates/bp-legacy/buddypress-functions.php:1080
+#: bp-themes/bp-default/_inc/ajax.php:646
 msgid "Friendship could not be canceled."
 msgstr ""
 
-#: bp-friends/bp-friends-actions.php:72
+#: bp-friends/bp-friends-actions.php:78
 msgid "Friendship canceled"
 msgstr ""
 
-#: bp-friends/bp-friends-actions.php:76
+#: bp-friends/bp-friends-actions.php:82
 msgid "You are not yet friends with this user"
 msgstr ""
 
-#: bp-friends/bp-friends-actions.php:78
+#: bp-friends/bp-friends-actions.php:84
 msgid "You have a pending friendship request with this user"
 msgstr ""
 
-#: bp-friends/bp-friends-activity.php:57
+#: bp-friends/bp-friends-activity.php:98
 msgid "Friendships accepted"
 msgstr ""
 
-#: bp-friends/bp-friends-activity.php:58
+#: bp-friends/bp-friends-activity.php:105
 msgid "New friendships"
 msgstr ""
 
-#: bp-friends/bp-friends-activity.php:61
+#: bp-friends/bp-friends-activity.php:110
 msgid "New friendship created"
 msgstr ""
 
-#: bp-friends/bp-friends-activity.php:86
-msgid "%d friends accepted your friendship requests"
-msgstr ""
-
-#: bp-friends/bp-friends-activity.php:89
-#: bp-friends/bp-friends-notifications.php:71
-msgid "%s accepted your friendship request"
-msgstr ""
-
-#: bp-friends/bp-friends-activity.php:100
-msgid "You have %d pending friendship requests"
-msgstr ""
-
-#: bp-friends/bp-friends-activity.php:103
-msgid "You have a friendship request from %s"
-msgstr ""
-
-#: bp-friends/bp-friends-functions.php:104
-#: bp-friends/bp-friends-functions.php:113
+#: bp-friends/bp-friends-activity.php:128
+#: bp-friends/bp-friends-activity.php:154
+#: tests/testcases/friends/activity.php:23
+#: tests/testcases/friends/activity.php:45
 msgid "%1$s and %2$s are now friends"
 msgstr ""
 
-#: bp-friends/bp-friends-loader.php:77
+#: bp-friends/bp-friends-loader.php:92
 msgid "Search Friends..."
 msgstr ""
 
-#: bp-friends/bp-friends-loader.php:97
-msgid "Friends <span>%d</span>"
+#: bp-friends/bp-friends-loader.php:119
+msgid "Friends <span class=\"%s\">%s</span>"
 msgstr ""
 
-#: bp-friends/bp-friends-loader.php:118 bp-friends/bp-friends-loader.php:180
-#: bp-friends/bp-friends-loader.php:207
+#: bp-friends/bp-friends-loader.php:140 bp-friends/bp-friends-loader.php:204
+#: bp-friends/bp-friends-loader.php:229
 #: bp-templates/bp-legacy/buddypress/activity/index.php:104
 #: bp-templates/bp-legacy/buddypress/members/single/activity.php:35
 #: bp-themes/bp-default/activity/index.php:124
@@ -2492,27 +2753,27 @@ msgstr ""
 msgid "Friendships"
 msgstr ""
 
-#: bp-friends/bp-friends-loader.php:128 bp-groups/bp-groups-template.php:1480
+#: bp-friends/bp-friends-loader.php:150 bp-groups/bp-groups-template.php:1524
 msgid "Requests"
 msgstr ""
 
-#: bp-friends/bp-friends-loader.php:161
+#: bp-friends/bp-friends-loader.php:185
 msgid "Friends <span class=\"count\">%s</span>"
 msgstr ""
 
-#: bp-friends/bp-friends-loader.php:162
+#: bp-friends/bp-friends-loader.php:186
 msgid "Pending Requests <span class=\"count\">%s</span>"
 msgstr ""
 
-#: bp-friends/bp-friends-loader.php:165
+#: bp-friends/bp-friends-loader.php:189
 msgid "No Pending Requests"
 msgstr ""
 
-#: bp-friends/bp-friends-notifications.php:31
+#: bp-friends/bp-friends-notifications.php:43
 msgid "New friendship request from %s"
 msgstr ""
 
-#: bp-friends/bp-friends-notifications.php:32
+#: bp-friends/bp-friends-notifications.php:44
 msgid ""
 "%1$s wants to add you as a friend.\n"
 "\n"
@@ -2523,7 +2784,12 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-friends/bp-friends-notifications.php:72
+#: bp-friends/bp-friends-notifications.php:94
+#: bp-friends/bp-friends-notifications.php:144
+msgid "%s accepted your friendship request"
+msgstr ""
+
+#: bp-friends/bp-friends-notifications.php:95
 msgid ""
 "%1$s accepted your friend request.\n"
 "\n"
@@ -2532,355 +2798,365 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-friends/bp-friends-screens.php:34
-msgid "Friendship accepted"
+#: bp-friends/bp-friends-notifications.php:141
+msgid "%d friends accepted your friendship requests"
+msgstr ""
+
+#: bp-friends/bp-friends-notifications.php:155
+msgid "You have %d pending friendship requests"
+msgstr ""
+
+#: bp-friends/bp-friends-notifications.php:158
+msgid "You have a friendship request from %s"
 msgstr ""
 
 #: bp-friends/bp-friends-screens.php:36
+msgid "Friendship accepted"
+msgstr ""
+
+#: bp-friends/bp-friends-screens.php:38
 msgid "Friendship could not be accepted"
 msgstr ""
 
-#: bp-friends/bp-friends-screens.php:45
+#: bp-friends/bp-friends-screens.php:47
 msgid "Friendship rejected"
 msgstr ""
 
-#: bp-friends/bp-friends-screens.php:47
+#: bp-friends/bp-friends-screens.php:49
 msgid "Friendship could not be rejected"
 msgstr ""
 
-#: bp-friends/bp-friends-screens.php:56
+#: bp-friends/bp-friends-screens.php:58
 msgid "Friendship request withdrawn"
 msgstr ""
 
-#: bp-friends/bp-friends-screens.php:58
+#: bp-friends/bp-friends-screens.php:60
 msgid "Friendship request could not be withdrawn"
 msgstr ""
 
-#: bp-friends/bp-friends-screens.php:92
+#: bp-friends/bp-friends-screens.php:94
 msgid "A member sends you a friendship request"
 msgstr ""
 
-#: bp-friends/bp-friends-screens.php:98
+#: bp-friends/bp-friends-screens.php:100
 msgid "A member accepts your friendship request"
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:69 bp-xprofile/bp-xprofile-loader.php:121
+#: bp-friends/bp-friends-template.php:66 bp-xprofile/bp-xprofile-loader.php:122
 msgid "My Friends"
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:69
+#: bp-friends/bp-friends-template.php:66
 msgid "%s's Friends"
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:69
+#: bp-friends/bp-friends-template.php:66
 msgid "See All"
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:89
+#: bp-friends/bp-friends-template.php:86
 msgid "You haven't added any friend connections yet."
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:89
+#: bp-friends/bp-friends-template.php:86
 msgid "%s hasn't created any friend connections yet."
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:159
+#: bp-friends/bp-friends-template.php:156
 msgid "There aren't enough site members to show a random sample just yet."
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:169
+#: bp-friends/bp-friends-template.php:173
 msgid "Filter Friends"
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:204
+#: bp-friends/bp-friends-template.php:221
 msgid "%d friend"
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:206
+#: bp-friends/bp-friends-template.php:223
 msgid "%d friends"
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:285
-#: bp-templates/bp-legacy/buddypress-functions.php:967
-#: bp-themes/bp-default/_inc/ajax.php:629
+#: bp-friends/bp-friends-template.php:318
+#: bp-templates/bp-legacy/buddypress-functions.php:1092
+#: bp-themes/bp-default/_inc/ajax.php:658
 msgid "Cancel Friendship Request"
 msgstr ""
 
-#: bp-friends/bp-friends-template.php:286
-msgid "Cancel Friendship Requested"
-msgstr ""
-
-#: bp-friends/bp-friends-template.php:302
-#: bp-friends/bp-friends-template.php:303
-msgid "Cancel Friendship"
-msgstr ""
-
 #: bp-friends/bp-friends-template.php:319
-#: bp-friends/bp-friends-template.php:320
-#: bp-templates/bp-legacy/buddypress-functions.php:957
-#: bp-templates/bp-legacy/buddypress-functions.php:975
-#: bp-themes/bp-default/_inc/ajax.php:619
-#: bp-themes/bp-default/_inc/ajax.php:637
-msgid "Add Friend"
+msgid "Cancel Friendship Requested"
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:28
-msgid "Sorry, you are not allowed to create groups."
+#: bp-friends/bp-friends-template.php:335
+#: bp-friends/bp-friends-template.php:336
+msgid "Friendship Requested"
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:50
-msgid "There was an error saving group details. Please try again."
+#: bp-friends/bp-friends-template.php:352
+#: bp-friends/bp-friends-template.php:353
+msgid "Cancel Friendship"
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:72
-msgid "Please fill in all of the required fields"
+#: bp-friends/bp-friends-template.php:369
+#: bp-friends/bp-friends-template.php:370
+#: bp-templates/bp-legacy/buddypress-functions.php:1082
+#: bp-templates/bp-legacy/buddypress-functions.php:1100
+#: bp-themes/bp-default/_inc/ajax.php:648
+#: bp-themes/bp-default/_inc/ajax.php:666
+msgid "Add Friend"
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:79 bp-groups/bp-groups-actions.php:103
-msgid "There was an error saving group details, please try again."
-msgstr ""
+#: bp-friends/bp-friends-template.php:588
+msgid "%s friend"
+msgid_plural "%s friends"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-groups/bp-groups-actions.php:142
-msgid "%1$s created the group %2$s"
+#: bp-friends/bp-friends-widgets.php:41
+msgid "A dynamic list of recently active, popular, and newest Friends of the displayed member.  Widget is only shown when viewing a member profile."
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:194
-msgid "There was an error saving the group avatar, please try uploading again."
+#: bp-friends/bp-friends-widgets.php:44
+msgctxt "widget name"
+msgid "(BuddyPress) Friends"
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:196
-msgid "The group avatar was uploaded successfully!"
+#: bp-friends/bp-friends-widgets.php:66
+msgid "%s&#8217;s Friends"
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:220 bp-groups/bp-groups-actions.php:227
-msgid "There was an error joining the group."
+#: bp-friends/bp-friends-widgets.php:128
+#: bp-templates/bp-legacy/buddypress/members/members-loop.php:108
+#: bp-themes/bp-default/members/members-loop.php:108
+msgid "Sorry, no members were found."
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:229
-msgid "You joined the group!"
+#: bp-friends/bp-friends-widgets.php:174
+msgid "Max friends to show:"
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:255 bp-groups/bp-groups-screens.php:711
-msgid "This group must have at least one admin"
+#: bp-friends/bp-friends-widgets.php:177
+msgid "Default friends to show:"
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:258
-msgid "There was an error leaving the group."
+#: bp-groups/bp-groups-actions.php:31
+msgid "Sorry, you are not allowed to create groups."
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:260 bp-groups/bp-groups-functions.php:309
-msgid "You successfully left the group."
+#: bp-groups/bp-groups-actions.php:54
+msgid "There was an error saving group details. Please try again."
 msgstr ""
 
-#: bp-groups/bp-groups-actions.php:334
-msgid "Activity feed for the group, %s."
+#: bp-groups/bp-groups-actions.php:69
+msgid "Only the group creator may continue editing this group."
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:23
-msgid "Created a group"
+#: bp-groups/bp-groups-actions.php:82
+msgid "Please fill in all of the required fields"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:24
-msgid "Joined a group"
+#: bp-groups/bp-groups-actions.php:89 bp-groups/bp-groups-actions.php:113
+msgid "There was an error saving group details, please try again."
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:30
-msgid "New group forum topic"
+#: bp-groups/bp-groups-actions.php:197 bp-groups/bp-groups-screens.php:472
+msgid "Invite successfully removed"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:31
-msgid "New group forum post"
+#: bp-groups/bp-groups-actions.php:201 bp-groups/bp-groups-screens.php:483
+msgid "There was an error removing the invite"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:108
-msgid "%1$d new membership requests for the group \"%2$s\""
+#: bp-groups/bp-groups-actions.php:232
+msgid "There was an error saving the group avatar, please try uploading again."
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:113
-msgid "Group Membership Requests"
+#: bp-groups/bp-groups-actions.php:234
+msgid "The group avatar was uploaded successfully!"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:122 bp-groups/bp-groups-activity.php:127
-msgid "%s requests group membership"
+#: bp-groups/bp-groups-actions.php:258 bp-groups/bp-groups-actions.php:265
+msgid "There was an error joining the group."
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:145
-msgid "%d accepted group membership requests"
+#: bp-groups/bp-groups-actions.php:267
+msgid "You joined the group!"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:158
-msgid "Membership for group \"%s\" accepted"
+#: bp-groups/bp-groups-actions.php:305 bp-groups/bp-groups-screens.php:753
+msgid "This group must have at least one admin"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:181
-msgid "%d rejected group membership requests"
+#: bp-groups/bp-groups-actions.php:307
+msgid "There was an error leaving the group."
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:194
-msgid "Membership for group \"%s\" rejected"
+#: bp-groups/bp-groups-actions.php:309 bp-groups/bp-groups-functions.php:317
+msgid "You successfully left the group."
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:217
-msgid "You were promoted to an admin in %d groups"
+#: bp-groups/bp-groups-actions.php:392
+msgid "Activity feed for the group, %s."
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:230
-msgid "You were promoted to an admin in the group \"%s\""
+#: bp-groups/bp-groups-activity.php:29
+msgid "Created a group"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:253
-msgid "You were promoted to a mod in %d groups"
+#: bp-groups/bp-groups-activity.php:36
+msgid "Joined a group"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:266
-msgid "You were promoted to a mod in the group \"%s\""
+#: bp-groups/bp-groups-activity.php:44
+msgid "New group forum topic"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:290
-msgid "You have %d new group invitations"
+#: bp-groups/bp-groups-activity.php:45
+msgid "New group forum post"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:294
-msgid "Group Invites"
+#: bp-groups/bp-groups-activity.php:70
+msgid "%1$s created the group %2$s"
 msgstr ""
 
-#: bp-groups/bp-groups-activity.php:302
-msgid "You have an invitation to the group: %s"
+#: bp-groups/bp-groups-activity.php:93 bp-groups/bp-groups-activity.php:259
+msgid "%1$s joined the group %2$s"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:109
+#: bp-groups/bp-groups-admin.php:113
 msgid "This page is a convenient way to edit the details associated with one of your groups."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:110
+#: bp-groups/bp-groups-admin.php:114
 msgid "The Name and Description box is fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of each box. Use the Screen Options tab to hide or unhide, or to choose a 1- or 2-column layout for this screen."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:116
+#: bp-groups/bp-groups-admin.php:120
 msgid "Support Forums"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:120
+#: bp-groups/bp-groups-admin.php:124
 msgctxt "group admin edit screen"
 msgid "Save"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:121
+#: bp-groups/bp-groups-admin.php:125
 msgctxt "group admin edit screen"
 msgid "Settings"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:122
+#: bp-groups/bp-groups-admin.php:126
 msgctxt "group admin edit screen"
 msgid "Add New Members"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:123
+#: bp-groups/bp-groups-admin.php:127
 msgctxt "group admin edit screen"
 msgid "Manage Members"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:138
+#: bp-groups/bp-groups-admin.php:141
 msgctxt "Groups per page (screen options)"
 msgid "Groups"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:145
+#: bp-groups/bp-groups-admin.php:148
 msgid "You can manage groups much like you can manage comments and other content. This screen is customizable in the same ways as other management screens, and you can act on groups by using the on-hover action links or the Bulk Actions."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:150
+#: bp-groups/bp-groups-admin.php:153
 msgid "Group Actions"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:152
+#: bp-groups/bp-groups-admin.php:155
 msgid "Clicking \"Visit\" will take you to the group&#8217;s public page. Use this link to see what the group looks like on the front end of your site."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:153
+#: bp-groups/bp-groups-admin.php:156
 msgid "Clicking \"Edit\" will take you to a Dashboard panel where you can manage various details about the group, such as its name and description, its members, and other settings."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:154
+#: bp-groups/bp-groups-admin.php:157
 msgid "If you click \"Delete\" under a specific group, or select a number of groups and then choose Delete from the Bulk Actions menu, you will be led to a page where you&#8217;ll be asked to confirm the permanent deletion of the group(s)."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:169
+#: bp-groups/bp-groups-admin.php:174
 msgid "Start typing a username to add a new member."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:170
+#: bp-groups/bp-groups-admin.php:175
 msgid "If you leave this page, you will lose any unsaved changes you have made to the group."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:444
+#: bp-groups/bp-groups-admin.php:453
 msgid "You cannot remove all administrators from a group."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:448
+#: bp-groups/bp-groups-admin.php:457
 msgid "An error occurred when trying to update your group details."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:450
+#: bp-groups/bp-groups-admin.php:459
 msgid "The group has been updated successfully."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:454
+#: bp-groups/bp-groups-admin.php:463
 msgid "The following users could not be added to the group: <em>%s</em>"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:458
+#: bp-groups/bp-groups-admin.php:467
 msgid "The following users were successfully added to the group: <em>%s</em>"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:463
+#: bp-groups/bp-groups-admin.php:472
 msgid "An error occurred when trying to modify the following members: <em>%s</em>"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:468
+#: bp-groups/bp-groups-admin.php:477
 msgid "The following members were successfully modified: <em>%s</em>"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:487 bp-groups/bp-groups-adminbar.php:40
+#: bp-groups/bp-groups-admin.php:496 bp-groups/bp-groups-adminbar.php:39
 #: bp-xprofile/bp-xprofile-admin.php:114
 msgid "Edit Group"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:490 bp-groups/bp-groups-admin.php:626
+#: bp-groups/bp-groups-admin.php:499 bp-groups/bp-groups-admin.php:641
 msgid "Add New"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:509
+#: bp-groups/bp-groups-admin.php:518
 msgid "Name and Description"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:536
+#: bp-groups/bp-groups-admin.php:545
 msgid "No group found with this ID. <a href=\"%s\">Go back and try again</a>."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:574
+#: bp-groups/bp-groups-admin.php:587
 msgid "Delete Groups"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:575
+#: bp-groups/bp-groups-admin.php:588
 msgid "You are about to delete the following groups:"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:583
+#: bp-groups/bp-groups-admin.php:596 bp-members/bp-members-admin.php:1421
 msgid "This action cannot be undone."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:610
+#: bp-groups/bp-groups-admin.php:625
 msgid "%s group has been permanently deleted."
 msgid_plural "%s groups have been permanently deleted."
 msgstr[0] ""
 msgstr[1] ""
 
-#: bp-groups/bp-groups-admin.php:643
+#: bp-groups/bp-groups-admin.php:658
 msgid "Search all Groups"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:665
+#: bp-groups/bp-groups-admin.php:681
 #: bp-templates/bp-legacy/buddypress/groups/create.php:112
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:47
 #: bp-themes/bp-default/groups/create.php:119
@@ -2888,29 +3164,29 @@ msgstr ""
 msgid "Enable discussion forum"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:670
+#: bp-groups/bp-groups-admin.php:687
 msgid "Privacy"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:673 bp-groups/bp-groups-admin.php:1385
-#: bp-groups/bp-groups-template.php:647
+#: bp-groups/bp-groups-admin.php:690 bp-groups/bp-groups-admin.php:1447
+#: bp-groups/bp-groups-template.php:663
 msgid "Public"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:674 bp-groups/bp-groups-admin.php:1388
-#: bp-groups/bp-groups-template.php:649
+#: bp-groups/bp-groups-admin.php:691 bp-groups/bp-groups-admin.php:1450
+#: bp-groups/bp-groups-template.php:665
 msgid "Private"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:675 bp-groups/bp-groups-admin.php:1391
+#: bp-groups/bp-groups-admin.php:692 bp-groups/bp-groups-admin.php:1453
 msgid "Hidden"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:679
+#: bp-groups/bp-groups-admin.php:699
 msgid "Who can invite others to this group?"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:682
+#: bp-groups/bp-groups-admin.php:702
 #: bp-templates/bp-legacy/buddypress/groups/create.php:89
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:99
 #: bp-themes/bp-default/groups/create.php:96
@@ -2918,7 +3194,7 @@ msgstr ""
 msgid "All group members"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:683
+#: bp-groups/bp-groups-admin.php:703
 #: bp-templates/bp-legacy/buddypress/groups/create.php:94
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:104
 #: bp-themes/bp-default/groups/create.php:101
@@ -2926,7 +3202,7 @@ msgstr ""
 msgid "Group admins and mods only"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:684
+#: bp-groups/bp-groups-admin.php:704
 #: bp-templates/bp-legacy/buddypress/groups/create.php:99
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:109
 #: bp-themes/bp-default/groups/create.php:106
@@ -2934,79 +3210,79 @@ msgstr ""
 msgid "Group admins only"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:699
+#: bp-groups/bp-groups-admin.php:720
 msgid "Enter a comma-separated list of user logins."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:757
+#: bp-groups/bp-groups-admin.php:779
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:177
 #: bp-themes/bp-default/groups/single/admin.php:177
 msgid "Administrators"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:758
+#: bp-groups/bp-groups-admin.php:780
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:205
 #: bp-themes/bp-default/groups/single/admin.php:205
 msgid "Moderators"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:760
+#: bp-groups/bp-groups-admin.php:782
 msgid "Banned Users"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:773
+#: bp-groups/bp-groups-admin.php:795
 msgctxt "Group member user_id in group admin"
 msgid "ID"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:774
+#: bp-groups/bp-groups-admin.php:796
 msgctxt "Group member name in group admin"
 msgid "Name"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:775
+#: bp-groups/bp-groups-admin.php:797
 msgctxt "Group member role in group admin"
 msgid "Group Role"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:797
+#: bp-groups/bp-groups-admin.php:819
 msgid "Administrator"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:798
+#: bp-groups/bp-groups-admin.php:820
 msgid "Moderator"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:799
+#: bp-groups/bp-groups-admin.php:821
 msgid "Member"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:800
+#: bp-groups/bp-groups-admin.php:822
 msgid "Banned"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:801
+#: bp-groups/bp-groups-admin.php:823
 msgid "Remove From Group"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:834
+#: bp-groups/bp-groups-admin.php:856
 msgid "No members of this type"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:859 bp-groups/bp-groups-adminbar.php:102
-#: bp-groups/bp-groups-buddybar.php:57
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:360
+#: bp-groups/bp-groups-admin.php:882 bp-groups/bp-groups-adminbar.php:101
+#: bp-groups/bp-groups-buddybar.php:58
+#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:332
 #: bp-themes/bp-default/groups/single/admin.php:360
 #: bp-xprofile/bp-xprofile-admin.php:118
 msgid "Delete Group"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:863 bp-groups/bp-groups-classes.php:2121
+#: bp-groups/bp-groups-admin.php:886 bp-groups/bp-groups-classes.php:3135
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:32
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:117
 #: bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php:58
 #: bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php:74
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:148
+#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:61
 #: bp-templates/bp-legacy/buddypress/members/single/settings/general.php:22
 #: bp-templates/bp-legacy/buddypress/members/single/settings/notifications.php:11
 #: bp-themes/bp-default/groups/single/admin.php:32
@@ -3016,23 +3292,23 @@ msgstr ""
 #: bp-themes/bp-default/members/single/profile/edit.php:148
 #: bp-themes/bp-default/members/single/settings/general.php:72
 #: bp-themes/bp-default/members/single/settings/notifications.php:61
-#: bp-xprofile/bp-xprofile-classes.php:360
+#: bp-xprofile/bp-xprofile-classes.php:460
 msgid "Save Changes"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:910
+#: bp-groups/bp-groups-admin.php:935
 msgid "&laquo;"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:911
+#: bp-groups/bp-groups-admin.php:936
 msgid "&raquo;"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:917
+#: bp-groups/bp-groups-admin.php:942
 msgid "Viewing %1$s - %2$s of %3$s"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:920 bp-groups/bp-groups-template.php:960
+#: bp-groups/bp-groups-admin.php:945 bp-groups/bp-groups-template.php:1004
 msgid "%s member"
 msgid_plural "%s members"
 msgstr[0] ""
@@ -3040,209 +3316,218 @@ msgstr[1] ""
 
 #. translators: 1: user_login, 2: user_email
 
-#: bp-groups/bp-groups-admin.php:983
+#: bp-groups/bp-groups-admin.php:1011
 msgid "%1$s (%2$s)"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:1155
+#: bp-groups/bp-groups-admin.php:1195
 msgid "No groups found."
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:1220
+#: bp-groups/bp-groups-admin.php:1268
 msgid "Public <span class=\"count\">(%s)</span>"
-msgstr ""
+msgid_plural "Public <span class=\"count\">(%s)</span>"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-groups/bp-groups-admin.php:1221
+#: bp-groups/bp-groups-admin.php:1269
 msgid "Private <span class=\"count\">(%s)</span>"
-msgstr ""
+msgid_plural "Private <span class=\"count\">(%s)</span>"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-groups/bp-groups-admin.php:1222
+#: bp-groups/bp-groups-admin.php:1270
 msgid "Hidden <span class=\"count\">(%s)</span>"
-msgstr ""
+msgid_plural "Hidden <span class=\"count\">(%s)</span>"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-groups/bp-groups-admin.php:1251
+#: bp-groups/bp-groups-admin.php:1302
 msgctxt "Groups admin Group Name column header"
 msgid "Name"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:1252
+#: bp-groups/bp-groups-admin.php:1303
 msgctxt "Groups admin Group Description column header"
 msgid "Description"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:1253
+#: bp-groups/bp-groups-admin.php:1304
 msgctxt "Groups admin Privacy Status column header"
 msgid "Status"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:1254
+#: bp-groups/bp-groups-admin.php:1305
 msgctxt "Groups admin Members column header"
 msgid "# Members"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:1255
+#: bp-groups/bp-groups-admin.php:1306
 msgctxt "Groups admin Last Active column header"
 msgid "Last Active"
 msgstr ""
 
-#: bp-groups/bp-groups-admin.php:1291
+#: bp-groups/bp-groups-admin.php:1345
 msgid "Select group %1$d"
 msgstr ""
 
-#: bp-groups/bp-groups-adminbar.php:48 bp-groups/bp-groups-buddybar.php:33
+#: bp-groups/bp-groups-adminbar.php:47 bp-groups/bp-groups-buddybar.php:34
 msgid "Edit Details"
 msgstr ""
 
-#: bp-groups/bp-groups-adminbar.php:56
+#: bp-groups/bp-groups-adminbar.php:55
 msgid "Edit Settings"
 msgstr ""
 
-#: bp-groups/bp-groups-adminbar.php:65 bp-members/bp-members-adminbar.php:107
+#: bp-groups/bp-groups-adminbar.php:64 bp-members/bp-members-adminbar.php:109
 msgid "Edit Avatar"
 msgstr ""
 
-#: bp-groups/bp-groups-adminbar.php:75 bp-groups/bp-groups-buddybar.php:45
+#: bp-groups/bp-groups-adminbar.php:74 bp-groups/bp-groups-buddybar.php:46
 msgid "Manage Invitations"
 msgstr ""
 
-#: bp-groups/bp-groups-adminbar.php:84 bp-groups/bp-groups-buddybar.php:49
+#: bp-groups/bp-groups-adminbar.php:83 bp-groups/bp-groups-buddybar.php:50
 msgid "Manage Members"
 msgstr ""
 
-#: bp-groups/bp-groups-adminbar.php:93 bp-groups/bp-groups-buddybar.php:53
+#: bp-groups/bp-groups-adminbar.php:92 bp-groups/bp-groups-buddybar.php:54
 msgid "Membership Requests"
 msgstr ""
 
-#: bp-groups/bp-groups-buddybar.php:30 bp-members/bp-members-buddybar.php:120
+#: bp-groups/bp-groups-buddybar.php:31 bp-members/bp-members-buddybar.php:94
 msgid "Admin Options"
 msgstr ""
 
-#: bp-groups/bp-groups-buddybar.php:35
+#: bp-groups/bp-groups-buddybar.php:36
 msgid "Group Settings"
 msgstr ""
 
-#: bp-groups/bp-groups-buddybar.php:39 bp-groups/bp-groups-loader.php:595
-#: bp-groups/bp-groups-template.php:2606
+#: bp-groups/bp-groups-buddybar.php:40 bp-groups/bp-groups-loader.php:614
 msgid "Group Avatar"
 msgstr ""
 
-#: bp-groups/bp-groups-classes.php:1303
+#: bp-groups/bp-groups-classes.php:2016
 msgid "Group Mod"
 msgstr ""
 
-#: bp-groups/bp-groups-classes.php:1309 bp-groups/bp-groups-functions.php:121
+#: bp-groups/bp-groups-classes.php:2022 bp-groups/bp-groups-functions.php:147
 msgid "Group Admin"
 msgstr ""
 
-#: bp-groups/bp-groups-forums.php:104 bp-groups/bp-groups-forums.php:253
+#: bp-groups/bp-groups-forums.php:107 bp-groups/bp-groups-forums.php:256
 msgid "%1$s replied to the forum topic %2$s in the group %3$s"
 msgstr ""
 
-#: bp-groups/bp-groups-forums.php:154
+#: bp-groups/bp-groups-forums.php:157
 msgid "%1$s started the forum topic %2$s in the group %3$s"
 msgstr ""
 
-#: bp-groups/bp-groups-forums.php:206
+#: bp-groups/bp-groups-forums.php:209
 msgid "%1$s edited the forum topic %2$s in the group %3$s"
 msgstr ""
 
-#: bp-groups/bp-groups-functions.php:290
+#: bp-groups/bp-groups-functions.php:307
 msgid "As the only Admin, you cannot leave the group."
 msgstr ""
 
-#: bp-groups/bp-groups-functions.php:353 bp-groups/bp-groups-functions.php:920
-#: bp-groups/bp-groups-screens.php:62
-msgid "%1$s joined the group %2$s"
+#: bp-groups/bp-groups-functions.php:667
+msgid "%1$s posted an update in the group %2$s"
 msgstr ""
 
-#: bp-groups/bp-groups-functions.php:614
-msgid "%1$s posted an update in the group %2$s"
+#: bp-groups/bp-groups-loader.php:150
+msgctxt "component directory title"
+msgid "Groups"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:144
+#: bp-groups/bp-groups-loader.php:152
 msgid "Search Groups..."
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:273
+#: bp-groups/bp-groups-loader.php:291
 msgid "You do not have access to this group."
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:288
+#: bp-groups/bp-groups-loader.php:306
 msgid "You are not an admin of this group."
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:298 bp-groups/bp-groups-template.php:1461
+#: bp-groups/bp-groups-loader.php:316 bp-groups/bp-groups-template.php:1505
 msgid "Details"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:310 bp-groups/bp-groups-template.php:1472
+#: bp-groups/bp-groups-loader.php:328 bp-groups/bp-groups-template.php:1516
 msgid "Avatar"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:318
+#: bp-groups/bp-groups-loader.php:336
 msgid "Invites"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:346
-msgid "Groups <span>%d</span>"
+#: bp-groups/bp-groups-loader.php:363
+msgid "Groups <span class=\"%s\">%s</span>"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:368 bp-groups/bp-groups-loader.php:398
-#: bp-groups/bp-groups-loader.php:537 bp-groups/bp-groups-loader.php:575
+#: bp-groups/bp-groups-loader.php:392 bp-groups/bp-groups-loader.php:422
+#: bp-groups/bp-groups-loader.php:560 bp-groups/bp-groups-loader.php:595
 msgid "Memberships"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:379
+#: bp-groups/bp-groups-loader.php:403
 msgid "Invitations"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:410
+#: bp-groups/bp-groups-loader.php:434
 msgctxt "Group home navigation title"
 msgid "Home"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:427 bp-groups/bp-groups-template.php:1793
-#: bp-groups/bp-groups-template.php:1794
-#: bp-templates/bp-legacy/buddypress-functions.php:1074
-#: bp-themes/bp-default/_inc/ajax.php:736
+#: bp-groups/bp-groups-loader.php:454 bp-groups/bp-groups-template.php:1870
+#: bp-groups/bp-groups-template.php:1871
+#: bp-templates/bp-legacy/buddypress-functions.php:1214
+#: bp-themes/bp-default/_inc/ajax.php:780
 msgid "Request Membership"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:439
+#: bp-groups/bp-groups-loader.php:466
 msgid "Forum"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:451
+#: bp-groups/bp-groups-loader.php:478
 msgid "Members <span>%s</span>"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:463
-#: bp-templates/bp-legacy/buddypress/groups/single/send-invites.php:60
+#: bp-groups/bp-groups-loader.php:490
+#: bp-templates/bp-legacy/buddypress/groups/single/invites-loop.php:90
 #: bp-themes/bp-default/groups/single/send-invites.php:60
 msgid "Send Invites"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:477
+#: bp-groups/bp-groups-loader.php:504
 msgid "Admin"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:518
+#: bp-groups/bp-groups-loader.php:541
 msgid "No Pending Invites"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:521
+#: bp-groups/bp-groups-loader.php:544
 msgid "Groups <span class=\"count\">%s</span>"
 msgstr ""
 
-#: bp-groups/bp-groups-loader.php:522
+#: bp-groups/bp-groups-loader.php:545
 msgid "Pending Invites <span class=\"count\">%s</span>"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:19
+#: bp-groups/bp-groups-loader.php:618
+msgid "No Group Avatar"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:21
 msgid "Group Details Updated"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:34
+#: bp-groups/bp-groups-notifications.php:36
 msgid ""
 "Group details for the group \"%1$s\" were updated:\n"
 "\n"
@@ -3251,11 +3536,11 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:75
+#: bp-groups/bp-groups-notifications.php:91
 msgid "Membership request for group: %s"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:77
+#: bp-groups/bp-groups-notifications.php:93
 msgid ""
 "%1$s wants to join the group \"%2$s\".\n"
 "\n"
@@ -3269,11 +3554,11 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:128
+#: bp-groups/bp-groups-notifications.php:151
 msgid "Membership request for group \"%s\" accepted"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:129
+#: bp-groups/bp-groups-notifications.php:152
 msgid ""
 "Your membership request for the group \"%1$s\" has been accepted.\n"
 "\n"
@@ -3282,11 +3567,11 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:138
+#: bp-groups/bp-groups-notifications.php:161
 msgid "Membership request for group \"%s\" rejected"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:139
+#: bp-groups/bp-groups-notifications.php:162
 msgid ""
 "Your membership request for the group \"%1$s\" has been rejected.\n"
 "\n"
@@ -3295,19 +3580,19 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:166
+#: bp-groups/bp-groups-notifications.php:191
 msgid "an administrator"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:169
+#: bp-groups/bp-groups-notifications.php:194
 msgid "a moderator"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:187
+#: bp-groups/bp-groups-notifications.php:221
 msgid "You have been promoted in the group: \"%s\""
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:188
+#: bp-groups/bp-groups-notifications.php:222
 msgid ""
 "You have been promoted to %1$s for the group: \"%2$s\".\n"
 "\n"
@@ -3316,11 +3601,11 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:238
+#: bp-groups/bp-groups-notifications.php:279
 msgid "You have an invitation to the group: \"%s\""
 msgstr ""
 
-#: bp-groups/bp-groups-notifications.php:240
+#: bp-groups/bp-groups-notifications.php:281
 msgid ""
 "One of your friends %1$s has invited you to the group: \"%2$s\".\n"
 "\n"
@@ -3333,227 +3618,297 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:54
+#: bp-groups/bp-groups-notifications.php:335
+msgid "%1$d new membership requests for the group \"%2$s\""
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:340
+msgid "Group Membership Requests"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:349
+#: bp-groups/bp-groups-notifications.php:354
+msgid "%s requests group membership"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:372
+msgid "%d accepted group membership requests"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:385
+msgid "Membership for group \"%s\" accepted"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:408
+msgid "%d rejected group membership requests"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:421
+msgid "Membership for group \"%s\" rejected"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:444
+msgid "You were promoted to an admin in %d groups"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:457
+msgid "You were promoted to an admin in the group \"%s\""
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:480
+msgid "You were promoted to a mod in %d groups"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:493
+msgid "You were promoted to a mod in the group \"%s\""
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:517
+msgid "You have %d new group invitations"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:521
+msgid "Group Invites"
+msgstr ""
+
+#: bp-groups/bp-groups-notifications.php:529
+msgid "You have an invitation to the group: %s"
+msgstr ""
+
+#: bp-groups/bp-groups-screens.php:44
 msgid "Group invite could not be accepted"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:56
+#: bp-groups/bp-groups-screens.php:46 bp-groups/bp-groups-screens.php:506
 msgid "Group invite accepted"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:76
+#: bp-groups/bp-groups-screens.php:71
 msgid "Group invite could not be rejected"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:78
+#: bp-groups/bp-groups-screens.php:73
 msgid "Group invite rejected"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:161
+#: bp-groups/bp-groups-screens.php:151
 msgid "It looks like you've already said that!"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:164
+#: bp-groups/bp-groups-screens.php:154
 msgid "There was an error when replying to that topic"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:166
+#: bp-groups/bp-groups-screens.php:156
 msgid "Your reply was posted successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:187
+#: bp-groups/bp-groups-screens.php:177
 msgid "There was an error when making that topic a sticky"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:189
+#: bp-groups/bp-groups-screens.php:179
 msgid "The topic was made sticky successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:202
+#: bp-groups/bp-groups-screens.php:192
 msgid "There was an error when unsticking that topic"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:204
+#: bp-groups/bp-groups-screens.php:194
 msgid "The topic was unstuck successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:217
+#: bp-groups/bp-groups-screens.php:207
 msgid "There was an error when closing that topic"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:219
+#: bp-groups/bp-groups-screens.php:209
 msgid "The topic was closed successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:232
+#: bp-groups/bp-groups-screens.php:222
 msgid "There was an error when opening that topic"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:234
+#: bp-groups/bp-groups-screens.php:224
 msgid "The topic was opened successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:257
+#: bp-groups/bp-groups-screens.php:247
 msgid "There was an error deleting the topic"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:259
+#: bp-groups/bp-groups-screens.php:249
 msgid "The topic was deleted successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:283
+#: bp-groups/bp-groups-screens.php:273
 msgid "There was an error when editing that topic"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:285
+#: bp-groups/bp-groups-screens.php:275
 msgid "The topic was edited successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:310
+#: bp-groups/bp-groups-screens.php:300
 msgid "There was an error deleting that post"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:312
+#: bp-groups/bp-groups-screens.php:302
 msgid "The post was deleted successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:336
+#: bp-groups/bp-groups-screens.php:326
 msgid "There was an error when editing that post"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:338
+#: bp-groups/bp-groups-screens.php:328
 msgid "The post was edited successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:354 bp-groups/bp-groups-screens.php:373
+#: bp-groups/bp-groups-screens.php:344 bp-groups/bp-groups-screens.php:363
 msgid "You have been banned from this group."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:387
+#: bp-groups/bp-groups-screens.php:377
 msgid "This group does not have a forum setup yet."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:446
+#: bp-groups/bp-groups-screens.php:436
 msgid "Group invites sent."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:478
-msgid "There was an error sending your group membership request, please try again."
+#: bp-groups/bp-groups-screens.php:477
+msgid "You are not allowed to send or remove invites"
 msgstr ""
 
 #: bp-groups/bp-groups-screens.php:480
+msgid "The member requested to join the group"
+msgstr ""
+
+#: bp-groups/bp-groups-screens.php:508
+msgid "There was an error accepting the group invitation, please try again."
+msgstr ""
+
+#: bp-groups/bp-groups-screens.php:520
+msgid "There was an error sending your group membership request, please try again."
+msgstr ""
+
+#: bp-groups/bp-groups-screens.php:522
 msgid "Your membership request was sent to the group administrator successfully. You will be notified when the group administrator responds to your request."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:529
+#: bp-groups/bp-groups-screens.php:571
 msgid "There was an error updating group details, please try again."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:531
+#: bp-groups/bp-groups-screens.php:573
 msgid "Group details were successfully updated."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:573
+#: bp-groups/bp-groups-screens.php:615
 msgid "There was an error updating group settings, please try again."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:575
+#: bp-groups/bp-groups-screens.php:617
 msgid "Group settings were successfully updated."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:607 bp-xprofile/bp-xprofile-actions.php:39
+#: bp-groups/bp-groups-screens.php:649 bp-xprofile/bp-xprofile-actions.php:39
 msgid "Your avatar was deleted successfully!"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:609 bp-xprofile/bp-xprofile-actions.php:41
+#: bp-groups/bp-groups-screens.php:651 bp-members/bp-members-admin.php:506
+#: bp-xprofile/bp-xprofile-actions.php:41
 msgid "There was a problem deleting that avatar, please try again."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:652
+#: bp-groups/bp-groups-screens.php:694
 msgid "There was a problem cropping the avatar."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:654
+#: bp-groups/bp-groups-screens.php:696
 msgid "The new group avatar was uploaded successfully."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:690
+#: bp-groups/bp-groups-screens.php:732
 msgid "There was an error when promoting that user, please try again"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:692
+#: bp-groups/bp-groups-screens.php:734
 msgid "User promoted successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:715
+#: bp-groups/bp-groups-screens.php:757
 msgid "There was an error when demoting that user, please try again"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:717
+#: bp-groups/bp-groups-screens.php:759
 msgid "User demoted successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:733
+#: bp-groups/bp-groups-screens.php:775
 msgid "There was an error when banning that user, please try again"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:735
+#: bp-groups/bp-groups-screens.php:777
 msgid "User banned successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:751
+#: bp-groups/bp-groups-screens.php:793
 msgid "There was an error when unbanning that user, please try again"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:753
+#: bp-groups/bp-groups-screens.php:795
 msgid "User ban removed successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:769
+#: bp-groups/bp-groups-screens.php:811
 msgid "There was an error removing that user from the group, please try again"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:771
+#: bp-groups/bp-groups-screens.php:813
 msgid "User removed successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:809
+#: bp-groups/bp-groups-screens.php:850
 msgid "There was an error accepting the membership request, please try again."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:811
+#: bp-groups/bp-groups-screens.php:852
 msgid "Group membership request accepted"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:820
+#: bp-groups/bp-groups-screens.php:861
 msgid "There was an error rejecting the membership request, please try again."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:822
+#: bp-groups/bp-groups-screens.php:863
 msgid "Group membership request rejected"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:854
+#: bp-groups/bp-groups-screens.php:895
 msgid "There was an error deleting the group, please try again."
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:856
+#: bp-groups/bp-groups-screens.php:897
 msgid "The group was deleted successfully"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:904
+#: bp-groups/bp-groups-screens.php:945
 msgid "A member invites you to join a group"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:910
+#: bp-groups/bp-groups-screens.php:951
 msgid "Group information is updated"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:916
+#: bp-groups/bp-groups-screens.php:957
 msgid "You are promoted to a group administrator or moderator"
 msgstr ""
 
-#: bp-groups/bp-groups-screens.php:922
+#: bp-groups/bp-groups-screens.php:963
 msgid "A member requests to join a private group for which you are an admin"
 msgstr ""
 
@@ -3567,61 +3922,61 @@ msgctxt "Group pagination next text"
 msgid "&rarr;"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:480
+#: bp-groups/bp-groups-template.php:482
 msgid "Public Group"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:482
+#: bp-groups/bp-groups-template.php:484
 msgid "Hidden Group"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:484
+#: bp-groups/bp-groups-template.php:486
 msgid "Private Group"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:486
+#: bp-groups/bp-groups-template.php:488
 msgid "Group"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:558
+#: bp-groups/bp-groups-template.php:560
 msgid "not yet active"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:740
+#: bp-groups/bp-groups-template.php:756
 msgid "Group creator avatar of %s"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:775
+#: bp-groups/bp-groups-template.php:805
 msgid "No Admins"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:802
+#: bp-groups/bp-groups-template.php:846
 msgid "No Mods"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:884
+#: bp-groups/bp-groups-template.php:928
 msgid "Filter Groups"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:932
-msgid "Viewing group %1$s to %2$s (of %3$s groups)"
-msgstr ""
+#: bp-groups/bp-groups-template.php:976
+msgid "Viewing group %1$s to %2$s (of %3$s group)"
+msgid_plural "Viewing group %1$s to %2$s (of %3$s groups)"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-groups/bp-groups-template.php:962
-#: bp-templates/bp-legacy/buddypress/members/single/groups/invites.php:14
-#: bp-themes/bp-default/members/single/groups/invites.php:14
+#: bp-groups/bp-groups-template.php:1006
 msgid "%s members"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1001
+#: bp-groups/bp-groups-template.php:1045
 msgid "%d topic"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1003
+#: bp-groups/bp-groups-template.php:1047
 msgid "%d topics"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1229 bp-groups/bp-groups-template.php:1294
+#: bp-groups/bp-groups-template.php:1273 bp-groups/bp-groups-template.php:1338
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:190
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:217
 #: bp-themes/bp-default/groups/single/admin.php:190
@@ -3629,16 +3984,16 @@ msgstr ""
 msgid "Demote to Member"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1242 bp-groups/bp-groups-template.php:1307
-#: bp-groups/bp-groups-template.php:2105
+#: bp-groups/bp-groups-template.php:1286 bp-groups/bp-groups-template.php:1351
+#: bp-groups/bp-groups-template.php:2315
 msgid "joined %s"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1265
+#: bp-groups/bp-groups-template.php:1309
 msgid "This group has no administrators"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1293
+#: bp-groups/bp-groups-template.php:1337
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:216
 #: bp-templates/bp-legacy/buddypress/groups/single/admin.php:272
 #: bp-themes/bp-default/groups/single/admin.php:216
@@ -3646,135 +4001,525 @@ msgstr ""
 msgid "Promote to Admin"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1327
+#: bp-groups/bp-groups-template.php:1371
 msgid "This group has no moderators"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1752 bp-groups/bp-groups-template.php:1753
-#: bp-templates/bp-legacy/buddypress-functions.php:1053
-#: bp-themes/bp-default/_inc/ajax.php:715
+#: bp-groups/bp-groups-template.php:1796 bp-groups/bp-groups-template.php:1797
+#: bp-templates/bp-legacy/buddypress-functions.php:1178
+#: bp-templates/bp-legacy/buddypress-functions.php:1191
+#: bp-themes/bp-default/_inc/ajax.php:744
+#: bp-themes/bp-default/_inc/ajax.php:757
 msgid "Leave Group"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1775 bp-groups/bp-groups-template.php:1776
-#: bp-templates/bp-legacy/buddypress-functions.php:1072
-#: bp-themes/bp-default/_inc/ajax.php:734
+#: bp-groups/bp-groups-template.php:1819 bp-groups/bp-groups-template.php:1820
+#: bp-templates/bp-legacy/buddypress-functions.php:1212
+#: bp-themes/bp-default/_inc/ajax.php:778
 msgid "Join Group"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1808 bp-groups/bp-groups-template.php:1809
+#: bp-groups/bp-groups-template.php:1838 bp-groups/bp-groups-template.php:1839
+msgid "Accept Invitation"
+msgstr ""
+
+#: bp-groups/bp-groups-template.php:1854 bp-groups/bp-groups-template.php:1855
 msgid "Request Sent"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1839
+#: bp-groups/bp-groups-template.php:1938
 msgid "This is a private group and you must request group membership in order to join."
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1841
+#: bp-groups/bp-groups-template.php:1940
 msgid "This is a private group. To join you must be a registered site member and request group membership."
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1844
+#: bp-groups/bp-groups-template.php:1943
 msgid "This is a private group. Your membership request is awaiting approval from the group administrator."
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:1848
+#: bp-groups/bp-groups-template.php:1947
 msgid "This is a hidden group and only invited members can join."
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:2153
-msgid "Viewing members %1$s to %2$s (of %3$s members)"
-msgstr ""
-
-#: bp-groups/bp-groups-template.php:2379
-msgid "Group avatar"
-msgstr ""
-
-#: bp-groups/bp-groups-template.php:2519 bp-groups/bp-groups-template.php:2543
-msgid "Recently Joined"
-msgstr ""
-
-#: bp-groups/bp-groups-template.php:2520 bp-groups/bp-groups-template.php:2546
-msgid "Most Popular"
-msgstr ""
-
-#: bp-groups/bp-groups-template.php:2521 bp-groups/bp-groups-template.php:2549
-msgid "Administrator Of"
-msgstr ""
+#: bp-groups/bp-groups-template.php:2363 bp-members/bp-members-template.php:353
+msgid "Viewing member %1$s to %2$s (of %3$s member)"
+msgid_plural "Viewing members %1$s to %2$s (of %3$s members)"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-groups/bp-groups-template.php:2522 bp-groups/bp-groups-template.php:2552
-msgid "Moderator Of"
+#: bp-groups/bp-groups-template.php:2415
+#: bp-notifications/bp-notifications-template.php:940
+#: bp-templates/bp-legacy/buddypress/blogs/index.php:36
+#: bp-templates/bp-legacy/buddypress/forums/index.php:42
+#: bp-templates/bp-legacy/buddypress/groups/index.php:36
+#: bp-templates/bp-legacy/buddypress/groups/single/forum.php:36
+#: bp-templates/bp-legacy/buddypress/members/index.php:35
+#: bp-templates/bp-legacy/buddypress/members/single/blogs.php:19
+#: bp-templates/bp-legacy/buddypress/members/single/forums.php:18
+#: bp-templates/bp-legacy/buddypress/members/single/friends.php:20
+#: bp-templates/bp-legacy/buddypress/members/single/groups.php:20
+#: bp-themes/bp-default/blogs/index.php:53
+#: bp-themes/bp-default/forums/index.php:60
+#: bp-themes/bp-default/groups/index.php:55
+#: bp-themes/bp-default/groups/single/forum.php:36
+#: bp-themes/bp-default/members/index.php:55
+#: bp-themes/bp-default/members/single/blogs.php:19
+#: bp-themes/bp-default/members/single/forums.php:18
+#: bp-themes/bp-default/members/single/friends.php:20
+#: bp-themes/bp-default/members/single/groups.php:20
+msgid "Order By:"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:2610
-msgid "No Group Avatar"
+#: bp-groups/bp-groups-template.php:2418
+msgid "Oldest"
+msgstr ""
+
+#: bp-groups/bp-groups-template.php:2419
+#: bp-templates/bp-legacy/buddypress/blogs/index.php:40
+#: bp-templates/bp-legacy/buddypress/groups/index.php:42
+#: bp-templates/bp-legacy/buddypress/members/index.php:41
+#: bp-templates/bp-legacy/buddypress/members/single/blogs.php:23
+#: bp-templates/bp-legacy/buddypress/members/single/friends.php:24
+#: bp-templates/bp-legacy/buddypress/members/single/groups.php:25
+#: bp-themes/bp-default/blogs/index.php:57
+#: bp-themes/bp-default/groups/index.php:60
+#: bp-themes/bp-default/members/index.php:62
+#: bp-themes/bp-default/members/single/blogs.php:23
+#: bp-themes/bp-default/members/single/friends.php:24
+#: bp-themes/bp-default/members/single/groups.php:25
+msgid "Alphabetical"
+msgstr ""
+
+#: bp-groups/bp-groups-template.php:2646 bp-groups/bp-groups-template.php:2896
+msgid "Group avatar"
+msgstr ""
+
+#: bp-groups/bp-groups-template.php:2789 bp-groups/bp-groups-template.php:2813
+msgid "Recently Joined"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:2811
+#: bp-groups/bp-groups-template.php:2790 bp-groups/bp-groups-template.php:2816
+msgid "Most Popular"
+msgstr ""
+
+#: bp-groups/bp-groups-template.php:2791 bp-groups/bp-groups-template.php:2819
+msgid "Administrator Of"
+msgstr ""
+
+#: bp-groups/bp-groups-template.php:2792 bp-groups/bp-groups-template.php:2822
+msgid "Moderator Of"
+msgstr ""
+
+#: bp-groups/bp-groups-template.php:3184
 msgid "requested %s"
 msgstr ""
 
-#: bp-groups/bp-groups-template.php:2986
+#: bp-groups/bp-groups-template.php:3236
+msgid "Viewing requests %1$s to %2$s (of %3$s request)"
+msgid_plural "Viewing request %1$s to %2$s (of %3$s requests)"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-groups/bp-groups-template.php:3531
+msgid "Viewing invitation %1$s to %2$s (of %3$s invitation)"
+msgid_plural "Viewing invitation %1$s to %2$s (of %3$s invitations)"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-groups/bp-groups-template.php:3547
 msgid "Group Activity RSS Feed"
 msgstr ""
 
-#: bp-groups/bp-groups-widgets.php:28
+#: bp-groups/bp-groups-template.php:3718
+msgid "%s group"
+msgid_plural "%s groups"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-groups/bp-groups-widgets.php:24
 msgid "A dynamic list of recently active, popular, and newest groups"
 msgstr ""
 
-#: bp-groups/bp-groups-widgets.php:31
+#: bp-groups/bp-groups-widgets.php:27
 msgctxt "widget name"
 msgid "(BuddyPress) Groups"
 msgstr ""
 
-#: bp-groups/bp-groups-widgets.php:78 bp-groups/bp-groups-widgets.php:181
+#: bp-groups/bp-groups-widgets.php:83 bp-groups/bp-groups-widgets.php:195
 msgid "created %s"
 msgstr ""
 
-#: bp-groups/bp-groups-widgets.php:97
+#: bp-groups/bp-groups-widgets.php:102
 msgid "There are no groups to display."
 msgstr ""
 
-#: bp-groups/bp-groups-widgets.php:134
+#: bp-groups/bp-groups-widgets.php:139
 msgid "Link widget title to Groups directory"
 msgstr ""
 
-#: bp-groups/bp-groups-widgets.php:136
+#: bp-groups/bp-groups-widgets.php:141
 msgid "Max groups to show:"
 msgstr ""
 
-#: bp-groups/bp-groups-widgets.php:139
+#: bp-groups/bp-groups-widgets.php:144
 msgid "Default groups to show:"
 msgstr ""
 
-#: bp-groups/bp-groups-widgets.php:199
+#: bp-groups/bp-groups-widgets.php:213
 msgid "No groups matched the current filter."
 msgstr ""
 
-#: bp-loader.php:162 bp-loader.php:169
+#: bp-loader.php:166 bp-loader.php:173
 msgid "Cheatin&#8217; huh?"
 msgstr ""
 
-#: bp-loader.php:547
+#: bp-loader.php:569
 msgid "BuddyPress Default"
 msgstr ""
 
-#: bp-members/bp-members-actions.php:45
-msgid "User marked as spammer. Spam users are visible only to site admins."
+#: bp-members/admin/bp-members-classes.php:102
+#: bp-members/admin/bp-members-classes.php:432
+#: bp-members/bp-members-admin.php:856
+msgctxt "signup users"
+msgid "Pending <span class=\"count\">(%s)</span>"
+msgstr ""
+
+#: bp-members/admin/bp-members-classes.php:129
+#: bp-members/admin/bp-members-classes.php:277
+#: bp-members/admin/bp-members-classes.php:447
+#: bp-members/admin/bp-members-classes.php:588
+#: bp-settings/bp-settings-loader.php:106
+#: bp-settings/bp-settings-loader.php:179
+#: bp-themes/bp-default/functions.php:645
+msgid "Email"
+msgstr ""
+
+#: bp-members/admin/bp-members-classes.php:130
+#: bp-members/admin/bp-members-classes.php:448
+msgid "Registered"
+msgstr ""
+
+#: bp-members/admin/bp-members-classes.php:131
+#: bp-members/admin/bp-members-classes.php:449
+msgid "Last Sent"
+msgstr ""
+
+#: bp-members/admin/bp-members-classes.php:132
+#: bp-members/admin/bp-members-classes.php:450
+msgid "# Times Emailed"
+msgstr ""
+
+#: bp-members/admin/bp-members-classes.php:143
+#: bp-members/admin/bp-members-classes.php:461
+msgctxt "Pending signup action"
+msgid "Activate"
+msgstr ""
+
+#: bp-members/admin/bp-members-classes.php:144
+#: bp-members/admin/bp-members-classes.php:462
+msgctxt "Pending signup action"
+msgid "Email"
 msgstr ""
 
-#: bp-members/bp-members-actions.php:47
+#: bp-members/admin/bp-members-classes.php:164
+#: bp-members/admin/bp-members-classes.php:481
+msgid "No pending accounts found."
+msgstr ""
+
+#: bp-members/admin/bp-members-classes.php:170
+#: bp-members/admin/bp-members-classes.php:172
+#: bp-members/admin/bp-members-classes.php:486
+msgid "Edit settings"
+msgstr ""
+
+#: bp-members/admin/bp-members-classes.php:175
+#: bp-members/admin/bp-members-classes.php:489
+msgid "Registration is disabled. %s"
+msgstr ""
+
+#: bp-members/bp-members-actions.php:53 bp-members/bp-members-admin.php:483
 msgid "User removed as spammer."
 msgstr ""
 
-#: bp-members/bp-members-actions.php:80
+#: bp-members/bp-members-actions.php:86
 msgid "%s has been deleted from the system."
 msgstr ""
 
-#: bp-members/bp-members-actions.php:82
+#: bp-members/bp-members-actions.php:88
 msgid "There was an error deleting %s from the system. Please try again."
 msgstr ""
 
+#: bp-members/bp-members-admin.php:190 bp-members/bp-members-admin.php:191
+#: bp-members/bp-members-adminbar.php:100
+#: bp-xprofile/bp-xprofile-template.php:688
+#: bp-xprofile/bp-xprofile-template.php:689
+msgid "Edit Profile"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:199 bp-members/bp-members-admin.php:200
+msgid "Manage Signups"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:331 bp-members/bp-members-admin.php:754
+msgid "Extended Profile"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:352
+msgid "No users were found"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:386
+msgid "This is the admin view of a user&#39;s profile."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:387
+msgid "In the main column, you can edit the fields of the user&#39;s extended profile."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:388
+msgid "In the right-hand column, you can update the user&#39;s status, delete the user&#39;s avatar, and view recent statistics."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:394
+msgid "<a href=\"http://codex.buddypress.org/buddypress-site-administration/managing-user-profiles/\">Managing Profiles</a>"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:399
+msgctxt "members user-admin edit screen"
+msgid "Status"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:477
+msgid "Avatar was deleted successfully!"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:495
+msgid "Profile updated."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:512
+msgid "User could not be removed as spammer."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:518
+msgid "User could not be marked as spammer."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:524
+msgid "An error occured while trying to update the profile."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:530 bp-xprofile/bp-xprofile-screens.php:96
+msgid "Please make sure you fill in all required fields in this profile field group before saving."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:536 bp-xprofile/bp-xprofile-screens.php:138
+msgid "There was a problem updating some of your profile information, please try again."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:550
+msgid "&larr; Back to Users"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:559
+msgid "Edit User"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:561 bp-members/bp-members-admin.php:1294
+msgctxt "user"
+msgid "Add New"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:563 bp-members/bp-members-admin.php:1296
+msgctxt "user"
+msgid "Add Existing"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:598
+msgid "No user found with this ID. <a href=\"%s\">Go back and try again</a>."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:625
+msgid "User account has not yet been activated"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:643
+msgid "Spammer"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:653
+msgid "Registered on: <strong>%1$s</strong>"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:663
+msgid "View Profile"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:664
+msgid "Update Profile"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:684 bp-xprofile/bp-xprofile-admin.php:760
+msgid "%s has been marked as a spammer. All BuddyPress data associated with the user has been removed"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:715
+msgid "Last active: <strong>%1$s</strong>"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:917
+msgctxt "Pending Accounts per page (screen options)"
+msgid "Pending Accounts"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:923
+msgid "This is the admininistration screen for pending accounts on your site."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:924
+msgid "From the screen options, you can customize the displayed columns and the pagination of this screen."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:925
+msgid "You can reorder the list of your pending accounts by clicking on the Username, Email or Registered column headers."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:926
+msgid "Using the search form, you can find pending accounts more easily. The Username and Email fields will be included in the search."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:931
+#: bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php:7
+#: bp-themes/bp-default/members/single/notifications/notifications-loop.php:7
+msgid "Actions"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:933
+msgid "Hovering over a row in the pending accounts list will display action links that allow you to manage pending accounts. You can perform the following actions:"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:934
+msgid "\"Email\" takes you to the confirmation screen before being able to send the activation link to the desired pending account. You can only send the activation email once per day."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:935
+msgid "\"Delete\" allows you to delete a pending account from your site. You will be asked to confirm this deletion."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:936
+msgid "By clicking on a Username you will be able to activate a pending account from the confirmation screen."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:937
+msgid "Bulk actions allow you to perform these 3 actions for the selected rows."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1089
+msgctxt "signup resent"
+msgid "%s activation email successfully sent! "
+msgid_plural "%s activation emails successfully sent! "
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1100
+msgctxt "signup notsent"
+msgid "%s activation email was not sent."
+msgid_plural "%s activation emails were not sent."
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1123
+msgctxt "signup resent"
+msgid "%s account successfully activated! "
+msgid_plural "%s accounts successfully activated! "
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1134
+msgctxt "signup notsent"
+msgid "%s account was not activated."
+msgid_plural "%s accounts were not activated."
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1157
+msgctxt "signup deleted"
+msgid "%s sign-up successfully deleted!"
+msgid_plural "%s sign-ups successfully deleted!"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1168
+msgctxt "signup notdeleted"
+msgid "%s sign-up was not deleted."
+msgid_plural "%s sign-ups were not deleted."
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1191
+msgid "There was a problem sending the activation emails, please try again."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1198
+msgid "There was a problem activating accounts, please try again."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1205
+msgid "There was a problem deleting sign-ups, please try again."
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1292
+msgid "Users"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1311
+msgid "Search Pending Accounts"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1357
+msgid "Delete Pending Accounts"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1358
+msgid "You are about to delete the following account:"
+msgid_plural "You are about to delete the following accounts:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1362
+msgid "Activate Pending Accounts"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1363
+msgid "You are about to activate the following account:"
+msgid_plural "You are about to activate the following accounts:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1367
+msgid "Resend Activation Emails"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1368
+msgid "You are about to resend an activation email to the following account:"
+msgid_plural "You are about to resend activation emails to the following accounts:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-members/bp-members-admin.php:1407
+msgid "Last notified: %s"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1410
+msgid "(less than 24 hours ago)"
+msgstr ""
+
+#: bp-members/bp-members-admin.php:1424
+msgid "Confirm"
+msgstr ""
+
 #: bp-members/bp-members-adminbar.php:38
 msgid "Edit My Profile"
 msgstr ""
@@ -3787,148 +4532,174 @@ msgstr ""
 msgid "Edit Member"
 msgstr ""
 
-#: bp-members/bp-members-adminbar.php:99
-#: bp-xprofile/bp-xprofile-template.php:927
-#: bp-xprofile/bp-xprofile-template.php:928
-msgid "Edit Profile"
-msgstr ""
-
-#: bp-members/bp-members-adminbar.php:118
-#: bp-members/bp-members-buddybar.php:131
+#: bp-members/bp-members-adminbar.php:121
+#: bp-members/bp-members-buddybar.php:105
 msgid "User Capabilities"
 msgstr ""
 
-#: bp-members/bp-members-adminbar.php:126
-#: bp-settings/bp-settings-loader.php:130
-#: bp-settings/bp-settings-loader.php:190
+#: bp-members/bp-members-adminbar.php:129
+#: bp-settings/bp-settings-loader.php:131
+#: bp-settings/bp-settings-loader.php:188
 #: bp-templates/bp-legacy/buddypress/members/single/settings/delete-account.php:27
 #: bp-themes/bp-default/members/single/settings/delete-account.php:50
 #: bp-themes/bp-default/members/single/settings/delete-account.php:76
 msgid "Delete Account"
 msgstr ""
 
-#: bp-members/bp-members-adminbar.php:173
-msgid "No new notifications"
+#: bp-members/bp-members-buddybar.php:49
+msgid "Blog Authors"
 msgstr ""
 
-#: bp-members/bp-members-buddybar.php:24 bp-settings/bp-settings-loader.php:105
-#: bp-settings/bp-settings-loader.php:181
-msgid "Notifications"
+#: bp-members/bp-members-buddybar.php:99
+msgid "Edit %s's Profile"
 msgstr ""
 
-#: bp-members/bp-members-buddybar.php:45
-msgid "No new notifications."
+#: bp-members/bp-members-buddybar.php:103
+msgid "Edit %s's Avatar"
 msgstr ""
 
-#: bp-members/bp-members-buddybar.php:75
-msgid "Blog Authors"
+#: bp-members/bp-members-buddybar.php:107
+msgid "Delete %s's Account"
 msgstr ""
 
-#: bp-members/bp-members-buddybar.php:125
-msgid "Edit %s's Profile"
+#: bp-members/bp-members-classes.php:308
+msgid "<strong>ERROR</strong>: Couldn&#8217;t register you. Please contact the <a href=\"mailto:%s\">webmaster</a>."
 msgstr ""
 
-#: bp-members/bp-members-buddybar.php:129
-msgid "Edit %s's Avatar"
+#: bp-members/bp-members-classes.php:512 bp-members/bp-members-classes.php:573
+#: bp-members/bp-members-classes.php:628
+msgid "the sign-up has already been activated."
 msgstr ""
 
-#: bp-members/bp-members-buddybar.php:133
-msgid "Delete %s's Account"
+#: bp-members/bp-members-functions.php:944
+msgid "User last_activity data is no longer stored in usermeta. Use bp_get_user_last_activity() instead."
 msgstr ""
 
-#: bp-members/bp-members-functions.php:927
-#: bp-members/bp-members-functions.php:1511
+#: bp-members/bp-members-functions.php:974
+msgid "User last_activity data is no longer stored in usermeta. Use bp_update_user_last_activity() instead."
+msgstr ""
+
+#: bp-members/bp-members-functions.php:1147
+#: bp-members/bp-members-functions.php:1899
 msgid "<strong>ERROR</strong>: Your account has been marked as a spammer."
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1101
+#: bp-members/bp-members-functions.php:1332
 msgid "Please check your email address."
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1104
-#: bp-members/bp-members-functions.php:1107
+#: bp-members/bp-members-functions.php:1335
+#: bp-members/bp-members-functions.php:1338
 msgid "Sorry, that email address is not allowed!"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1110
+#: bp-members/bp-members-functions.php:1341
 msgid "Sorry, that email address is already used!"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1128
+#: bp-members/bp-members-functions.php:1372
 msgid "Please enter a username"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1136
+#: bp-members/bp-members-functions.php:1378
 msgid "That username is not allowed"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1139
-msgid "Usernames can contain only letters, numbers, ., -, *, and @"
+#: bp-members/bp-members-functions.php:1383
+msgid "Usernames can contain only letters, numbers, ., -, and @"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1142
+#: bp-members/bp-members-functions.php:1388
 msgid "Username must be at least 4 characters"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1145
+#: bp-members/bp-members-functions.php:1393
 msgid "Sorry, usernames may not contain the character \"_\"!"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1152
+#: bp-members/bp-members-functions.php:1400
 msgid "Sorry, usernames must have letters too!"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1156
+#: bp-members/bp-members-functions.php:1412
 msgid "Sorry, that username already exists!"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1201
-msgid "<strong>ERROR</strong>: Couldn&#8217;t register you... please contact the <a href=\"mailto:%s\">webmaster</a> !"
+#: bp-members/bp-members-functions.php:1531
+msgid "Invalid activation key."
+msgstr ""
+
+#: bp-members/bp-members-functions.php:1538
+msgid "The user is already active."
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1299
-#: bp-members/bp-members-functions.php:1303
+#: bp-members/bp-members-functions.php:1540
+msgid "The site is already active."
+msgstr ""
+
+#: bp-members/bp-members-functions.php:1558
 msgid "Invalid activation key"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1340
-msgid "%s became a registered member"
+#: bp-members/bp-members-functions.php:1573
+msgid "Could not create user"
 msgstr ""
 
-#: bp-members/bp-members-functions.php:1424
+#: bp-members/bp-members-functions.php:1587
+msgid "That username is already activated."
+msgstr ""
+
+#: bp-members/bp-members-functions.php:1772
+msgid "If you have not received an email yet, <a href=\"%s\">click here to resend it</a>."
+msgstr ""
+
+#: bp-members/bp-members-functions.php:1774
 msgid "<strong>ERROR</strong>: Your account has not been activated. Check your email for the activation link."
 msgstr ""
 
-#: bp-members/bp-members-loader.php:68
+#: bp-members/bp-members-functions.php:1805
+msgid "<strong>ERROR</strong>: Your account has already been activated."
+msgstr ""
+
+#: bp-members/bp-members-functions.php:1807
+msgid "Activation email resent!  Please check your inbox or spam folder."
+msgstr ""
+
+#: bp-members/bp-members-loader.php:76
+msgctxt "component directory title"
+msgid "Members"
+msgstr ""
+
+#: bp-members/bp-members-loader.php:81
 msgid "Search Members..."
 msgstr ""
 
-#: bp-members/bp-members-loader.php:193
+#: bp-members/bp-members-loader.php:219
 msgid "You"
 msgstr ""
 
-#: bp-members/bp-members-screens.php:94
+#: bp-members/bp-members-screens.php:92
 msgid "Please make sure you enter your password twice"
 msgstr ""
 
-#: bp-members/bp-members-screens.php:98
+#: bp-members/bp-members-screens.php:96
 msgid "The passwords you entered do not match."
 msgstr ""
 
-#: bp-members/bp-members-screens.php:121
+#: bp-members/bp-members-screens.php:119
 msgid "This is a required field"
 msgstr ""
 
-#: bp-members/bp-members-screens.php:254
+#: bp-members/bp-members-screens.php:261
 msgid "Your account is now active!"
 msgstr ""
 
-#: bp-members/bp-members-screens.php:515
-#: bp-themes/bp-default/registration/register.php:253
+#: bp-members/bp-members-screens.php:522
+#: bp-themes/bp-default/registration/register.php:259
 msgid "Check Your Email To Activate Your Account!"
 msgstr ""
 
-#: bp-members/bp-members-screens.php:523
+#: bp-members/bp-members-screens.php:530
 #: bp-themes/bp-default/registration/activate.php:11
 msgid "Account Activated"
 msgstr ""
@@ -3944,40 +4715,42 @@ msgid "&rarr;"
 msgstr ""
 
 #: bp-members/bp-members-template.php:347
-msgid "Viewing member %1$s to %2$s (of %3$s active members)"
-msgstr ""
+msgid "Viewing member %1$s to %2$s (of %3$s active member)"
+msgid_plural "Viewing member %1$s to %2$s (of %3$s active members)"
+msgstr[0] ""
+msgstr[1] ""
 
 #: bp-members/bp-members-template.php:349
-msgid "Viewing member %1$s to %2$s (of %3$s members with friends)"
-msgstr ""
+msgid "Viewing member %1$s to %2$s (of %3$s member with friends)"
+msgid_plural "Viewing member %1$s to %2$s (of %3$s members with friends)"
+msgstr[0] ""
+msgstr[1] ""
 
 #: bp-members/bp-members-template.php:351
-msgid "Viewing member %1$s to %2$s (of %3$s members online)"
-msgstr ""
-
-#: bp-members/bp-members-template.php:353
-msgid "Viewing member %1$s to %2$s (of %3$s members)"
-msgstr ""
+msgid "Viewing member %1$s to %2$s (of %3$s member online)"
+msgid_plural "Viewing member %1$s to %2$s (of %3$s members online)"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-members/bp-members-template.php:598
+#: bp-members/bp-members-template.php:621
 msgid "Never active"
 msgstr ""
 
-#: bp-members/bp-members-template.php:620
+#: bp-members/bp-members-template.php:644
 msgctxt "member latest update in member directory"
 msgid "- &quot;%s &quot;"
 msgstr ""
 
-#: bp-members/bp-members-template.php:677
+#: bp-members/bp-members-template.php:738
 msgctxt "Records the timestamp that the user registered into the activy stream"
 msgid "registered %s"
 msgstr ""
 
-#: bp-members/bp-members-template.php:1146
+#: bp-members/bp-members-template.php:1207
 msgid "Your Avatar"
 msgstr ""
 
-#: bp-members/bp-members-template.php:1216
+#: bp-members/bp-members-template.php:1277
 msgid "Activity RSS Feed"
 msgstr ""
 
@@ -4002,12 +4775,12 @@ msgid "There was an error deleting messages."
 msgstr ""
 
 #: bp-messages/bp-messages-actions.php:91
-#: bp-templates/bp-legacy/buddypress-functions.php:1233
-#: bp-themes/bp-default/_inc/ajax.php:883
+#: bp-templates/bp-legacy/buddypress-functions.php:1370
+#: bp-themes/bp-default/_inc/ajax.php:927
 msgid "Messages deleted."
 msgstr ""
 
-#: bp-messages/bp-messages-classes.php:261
+#: bp-messages/bp-messages-classes.php:466
 msgid "%s Recipients"
 msgstr ""
 
@@ -4019,73 +4792,65 @@ msgstr ""
 msgid "No Subject"
 msgstr ""
 
-#: bp-messages/bp-messages-functions.php:246
-#: bp-messages/bp-messages-loader.php:131
-#: bp-messages/bp-messages-loader.php:200
-msgid "Inbox"
-msgstr ""
-
-#: bp-messages/bp-messages-functions.php:249
-msgid "You have %d new messages"
+#: bp-messages/bp-messages-loader.php:33
+msgid "Private Messages"
 msgstr ""
 
-#: bp-messages/bp-messages-functions.php:252
-msgid "You have %d new message"
+#: bp-messages/bp-messages-loader.php:91
+msgid "Search Messages..."
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:33
-msgid "Private Messages"
+#: bp-messages/bp-messages-loader.php:109
+msgid "Messages <span class=\"%s\">%s</span>"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:87
-msgid "Search Messages..."
+#: bp-messages/bp-messages-loader.php:111
+#: bp-messages/bp-messages-loader.php:202
+#: bp-messages/bp-messages-screens.php:168
+msgid "Messages"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:104
-#: bp-messages/bp-messages-screens.php:104
-msgid "Messages <span>%s</span>"
+#: bp-messages/bp-messages-loader.php:139
+#: bp-messages/bp-messages-loader.php:203
+#: bp-messages/bp-messages-notifications.php:117
+msgid "Inbox"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:141
-#: bp-messages/bp-messages-loader.php:223
+#: bp-messages/bp-messages-loader.php:149
+#: bp-messages/bp-messages-loader.php:226
 msgid "Sent"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:151
-#: bp-messages/bp-messages-loader.php:231
+#: bp-messages/bp-messages-loader.php:159
+#: bp-messages/bp-messages-loader.php:234
 msgid "Compose"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:162
+#: bp-messages/bp-messages-loader.php:170
 msgid "Notices"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:196
+#: bp-messages/bp-messages-loader.php:199
 msgid "Messages <span class=\"count\">%s</span>"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:197
+#: bp-messages/bp-messages-loader.php:200
 msgid "Inbox <span class=\"count\">%s</span>"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:199
-#: bp-messages/bp-messages-screens.php:168
-msgid "Messages"
-msgstr ""
-
-#: bp-messages/bp-messages-loader.php:240
+#: bp-messages/bp-messages-loader.php:243
 msgid "All Member Notices"
 msgstr ""
 
-#: bp-messages/bp-messages-loader.php:259
+#: bp-messages/bp-messages-loader.php:260
 msgid "My Messages"
 msgstr ""
 
-#: bp-messages/bp-messages-notifications.php:50
+#: bp-messages/bp-messages-notifications.php:69
 msgid "New message from %s"
 msgstr ""
 
-#: bp-messages/bp-messages-notifications.php:52
+#: bp-messages/bp-messages-notifications.php:71
 msgid ""
 "%1$s sent you a new message:\n"
 "\n"
@@ -4098,6 +4863,18 @@ msgid ""
 "---------------------\n"
 msgstr ""
 
+#: bp-messages/bp-messages-notifications.php:120
+msgid "You have %d new messages"
+msgstr ""
+
+#: bp-messages/bp-messages-notifications.php:130
+msgid "%s sent you a new private message"
+msgstr ""
+
+#: bp-messages/bp-messages-notifications.php:132
+msgid "You have %d new private messages"
+msgstr ""
+
 #: bp-messages/bp-messages-screens.php:56
 #: bp-messages/bp-messages-screens.php:78
 msgid "There was an error sending that message, please try again"
@@ -4115,6 +4892,10 @@ msgstr ""
 msgid "Message sent successfully!"
 msgstr ""
 
+#: bp-messages/bp-messages-screens.php:104
+msgid "Messages <span>%s</span>"
+msgstr ""
+
 #: bp-messages/bp-messages-screens.php:125
 msgid "There was a problem deactivating that notice."
 msgstr ""
@@ -4153,127 +4934,221 @@ msgctxt "Message pagination next text"
 msgid "&rarr;"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:352
-msgid "Viewing message %1$s to %2$s (of %3$s messages)"
-msgstr ""
+#: bp-messages/bp-messages-template.php:456
+msgid "Viewing message %1$s to %2$s (of %3$s message)"
+msgid_plural "Viewing message %1$s to %2$s (of %3$s messages)"
+msgstr[0] ""
+msgstr[1] ""
 
-#: bp-messages/bp-messages-template.php:428
+#: bp-messages/bp-messages-template.php:532
 msgid "Select:"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:432
+#: bp-messages/bp-messages-template.php:536
+#: bp-notifications/bp-notifications-loader.php:151
+#: bp-notifications/bp-notifications-loader.php:212
+#: bp-notifications/bp-notifications-template.php:733
 msgid "Read"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:433
+#: bp-messages/bp-messages-template.php:537
+#: bp-notifications/bp-notifications-loader.php:140
+#: bp-notifications/bp-notifications-loader.php:189
+#: bp-notifications/bp-notifications-template.php:763
 msgid "Unread"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:439
+#: bp-messages/bp-messages-template.php:543
 msgid "Mark as Read"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:440
+#: bp-messages/bp-messages-template.php:544
 msgid "Mark as Unread"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:444
+#: bp-messages/bp-messages-template.php:548
 msgid "Delete Selected"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:489
+#: bp-messages/bp-messages-template.php:593
 msgid "Currently Active"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:556
+#: bp-messages/bp-messages-template.php:660
 msgid "Deactivate"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:607
-#: bp-templates/bp-legacy/buddypress/members/register.php:166
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:130
-#: bp-templates/bp-legacy/buddypress-functions.php:236
+#: bp-messages/bp-messages-template.php:709
+#: bp-templates/bp-legacy/buddypress/members/register.php:89
+#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:43
+#: bp-templates/bp-legacy/buddypress-functions.php:237
 #: bp-themes/bp-default/functions.php:165
 #: bp-themes/bp-default/members/single/profile/edit.php:130
-#: bp-themes/bp-default/registration/register.php:171
+#: bp-themes/bp-default/registration/register.php:173
+#: bp-xprofile/bp-xprofile-admin.php:736
 msgid "Close"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:652
+#: bp-messages/bp-messages-template.php:754
 msgid "Send a private message to this user."
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:653
+#: bp-messages/bp-messages-template.php:755
 msgid "Private Message"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:836
+#: bp-messages/bp-messages-template.php:938
 msgid "%d Recipients"
 msgstr ""
 
-#: bp-messages/bp-messages-template.php:924
-#: bp-templates/bp-legacy/buddypress-functions.php:1139
-#: bp-themes/bp-default/_inc/ajax.php:789
+#: bp-messages/bp-messages-template.php:1047
+#: bp-templates/bp-legacy/buddypress-functions.php:1279
+#: bp-themes/bp-default/_inc/ajax.php:833
 msgid "Sent %s"
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:157
+#: bp-messages/bp-messages-widgets.php:34
+msgid "(BuddyPress) Sitewide Notices"
+msgstr ""
+
+#: bp-messages/bp-messages-widgets.php:37
+msgid "Display Sitewide Notices posted by the site administrator"
+msgstr ""
+
+#: bp-notifications/bp-notifications-actions.php:43
+msgid "Notification successfully marked read."
+msgstr ""
+
+#: bp-notifications/bp-notifications-actions.php:45
+#: bp-notifications/bp-notifications-actions.php:81
+msgid "There was a problem marking that notification."
+msgstr ""
+
+#: bp-notifications/bp-notifications-actions.php:79
+msgid "Notification successfully marked unread."
+msgstr ""
+
+#: bp-notifications/bp-notifications-actions.php:115
+msgid "Notification successfully deleted."
+msgstr ""
+
+#: bp-notifications/bp-notifications-actions.php:117
+msgid "There was a problem deleting that notification."
+msgstr ""
+
+#: bp-notifications/bp-notifications-adminbar.php:54
+msgid "No new notifications"
+msgstr ""
+
+#: bp-notifications/bp-notifications-buddybar.php:49
+msgid "No new notifications."
+msgstr ""
+
+#: bp-notifications/bp-notifications-loader.php:86
+msgid "Search Notifications..."
+msgstr ""
+
+#: bp-notifications/bp-notifications-loader.php:111
+msgid "Notifications <span class=\"%s\">%s</span>"
+msgstr ""
+
+#: bp-notifications/bp-notifications-loader.php:185
+msgid "Notifications <span class=\"count\">%s</span>"
+msgstr ""
+
+#: bp-notifications/bp-notifications-loader.php:186
+msgid "Unread <span class=\"count\">%s</span>"
+msgstr ""
+
+#: bp-notifications/bp-notifications-template.php:327
+msgctxt "Notifications pagination previous text"
+msgid "&larr;"
+msgstr ""
+
+#: bp-notifications/bp-notifications-template.php:328
+msgctxt "Notifications pagination next text"
+msgid "&rarr;"
+msgstr ""
+
+#: bp-notifications/bp-notifications-template.php:664
+msgid "Date not found"
+msgstr ""
+
+#: bp-notifications/bp-notifications-template.php:895
+msgid "Viewing %1$s to %2$s (of %3$s notification)"
+msgid_plural "Viewing %1$s to %2$s (of %3$s notifications)"
+msgstr[0] ""
+msgstr[1] ""
+
+#: bp-notifications/bp-notifications-template.php:943
+msgid "Newest First"
+msgstr ""
+
+#: bp-notifications/bp-notifications-template.php:944
+msgid "Oldest First"
+msgstr ""
+
+#: bp-notifications/bp-notifications-template.php:948
+msgid "Go"
+msgstr ""
+
+#: bp-settings/bp-settings-actions.php:159
 msgid "That email address is invalid. Check the formatting and try again."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:160
+#: bp-settings/bp-settings-actions.php:162
 msgid "That email address is currently unavailable for use."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:163
+#: bp-settings/bp-settings-actions.php:165
 msgid "That email address is already taken."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:166
+#: bp-settings/bp-settings-actions.php:168
 msgid "Email address cannot be empty."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:176
+#: bp-settings/bp-settings-actions.php:178
 msgid "Your current password is invalid."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:179
+#: bp-settings/bp-settings-actions.php:181
 msgid "The new password fields did not match."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:182
+#: bp-settings/bp-settings-actions.php:184
 msgid "One of the password fields was empty."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:191
+#: bp-settings/bp-settings-actions.php:193
 msgid "Your settings have been saved."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:197
+#: bp-settings/bp-settings-actions.php:199
 msgid "No changes were made to your account."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:199
+#: bp-settings/bp-settings-actions.php:201
 msgid "No changes were made to this account."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:247
+#: bp-settings/bp-settings-actions.php:249
 msgid "Your notification settings have been saved."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:249
+#: bp-settings/bp-settings-actions.php:251
 msgid "This user's notification settings have been saved."
 msgstr ""
 
-#: bp-settings/bp-settings-actions.php:338
+#: bp-settings/bp-settings-actions.php:346
 msgid "%s was successfully deleted."
 msgstr ""
 
-#: bp-settings/bp-settings-loader.php:94 bp-settings/bp-settings-loader.php:173
+#: bp-settings/bp-settings-loader.php:94 bp-settings/bp-settings-loader.php:171
 msgid "General"
 msgstr ""
 
-#: bp-settings/bp-settings-loader.php:117
+#: bp-settings/bp-settings-loader.php:118
 #: bp-themes/bp-default/members/single/settings/capabilities.php:49
 msgid "Capabilities"
 msgstr ""
@@ -4311,9 +5186,9 @@ msgid "Mark as Favorite"
 msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/activity/entry.php:66
-#: bp-templates/bp-legacy/buddypress-functions.php:238
-#: bp-templates/bp-legacy/buddypress-functions.php:831
-#: bp-templates/bp-legacy/buddypress-functions.php:848
+#: bp-templates/bp-legacy/buddypress-functions.php:240
+#: bp-templates/bp-legacy/buddypress-functions.php:925
+#: bp-templates/bp-legacy/buddypress-functions.php:942
 #: bp-themes/bp-default/_inc/ajax.php:494
 #: bp-themes/bp-default/_inc/ajax.php:511
 #: bp-themes/bp-default/activity/entry.php:68
@@ -4322,9 +5197,9 @@ msgid "Favorite"
 msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/activity/entry.php:70
-#: bp-templates/bp-legacy/buddypress-functions.php:239
-#: bp-templates/bp-legacy/buddypress-functions.php:829
-#: bp-templates/bp-legacy/buddypress-functions.php:850
+#: bp-templates/bp-legacy/buddypress-functions.php:243
+#: bp-templates/bp-legacy/buddypress-functions.php:923
+#: bp-templates/bp-legacy/buddypress-functions.php:944
 #: bp-themes/bp-default/_inc/ajax.php:492
 #: bp-themes/bp-default/_inc/ajax.php:513
 #: bp-themes/bp-default/activity/entry.php:72
@@ -4523,27 +5398,6 @@ msgstr ""
 msgid "My Sites <span>%s</span>"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/blogs/index.php:36
-#: bp-templates/bp-legacy/buddypress/forums/index.php:42
-#: bp-templates/bp-legacy/buddypress/groups/index.php:36
-#: bp-templates/bp-legacy/buddypress/groups/single/forum.php:36
-#: bp-templates/bp-legacy/buddypress/members/index.php:35
-#: bp-templates/bp-legacy/buddypress/members/single/blogs.php:19
-#: bp-templates/bp-legacy/buddypress/members/single/forums.php:18
-#: bp-templates/bp-legacy/buddypress/members/single/friends.php:20
-#: bp-templates/bp-legacy/buddypress/members/single/groups.php:20
-#: bp-themes/bp-default/blogs/index.php:53
-#: bp-themes/bp-default/forums/index.php:60
-#: bp-themes/bp-default/groups/index.php:55
-#: bp-themes/bp-default/groups/single/forum.php:36
-#: bp-themes/bp-default/members/index.php:55
-#: bp-themes/bp-default/members/single/blogs.php:19
-#: bp-themes/bp-default/members/single/forums.php:18
-#: bp-themes/bp-default/members/single/friends.php:20
-#: bp-themes/bp-default/members/single/groups.php:20
-msgid "Order By:"
-msgstr ""
-
 #: bp-templates/bp-legacy/buddypress/blogs/index.php:38
 #: bp-templates/bp-legacy/buddypress/forums/index.php:44
 #: bp-templates/bp-legacy/buddypress/groups/index.php:39
@@ -4565,21 +5419,6 @@ msgstr ""
 msgid "Last Active"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/blogs/index.php:40
-#: bp-templates/bp-legacy/buddypress/groups/index.php:42
-#: bp-templates/bp-legacy/buddypress/members/index.php:41
-#: bp-templates/bp-legacy/buddypress/members/single/blogs.php:23
-#: bp-templates/bp-legacy/buddypress/members/single/friends.php:24
-#: bp-templates/bp-legacy/buddypress/members/single/groups.php:25
-#: bp-themes/bp-default/blogs/index.php:57
-#: bp-themes/bp-default/groups/index.php:60
-#: bp-themes/bp-default/members/index.php:62
-#: bp-themes/bp-default/members/single/blogs.php:23
-#: bp-themes/bp-default/members/single/friends.php:24
-#: bp-themes/bp-default/members/single/groups.php:25
-msgid "Alphabetical"
-msgstr ""
-
 #: bp-templates/bp-legacy/buddypress/forums/forums-loop.php:39
 #: bp-themes/bp-default/forums/forums-loop.php:39
 msgid "Topic"
@@ -4676,7 +5515,10 @@ msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/forums/index.php:98
 #: bp-themes/bp-default/forums/index.php:116
-#: bp-xprofile/bp-xprofile-template.php:476
+#: bp-xprofile/bp-xprofile-classes.php:1593
+#: bp-xprofile/bp-xprofile-classes.php:1618
+#: bp-xprofile/bp-xprofile-classes.php:1626
+#: bp-xprofile/bp-xprofile-classes.php:2190
 msgid "----"
 msgstr ""
 
@@ -4869,23 +5711,22 @@ msgid "Crop Image"
 msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/groups/create.php:204
-#: bp-templates/bp-legacy/buddypress/groups/single/send-invites.php:22
+#: bp-templates/bp-legacy/buddypress/groups/single/invites-loop.php:79
 #: bp-themes/bp-default/groups/create.php:211
 #: bp-themes/bp-default/groups/single/send-invites.php:22
 msgid "Select people to invite from your friends list."
 msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/groups/create.php:222
-#: bp-templates/bp-legacy/buddypress/groups/single/send-invites.php:42
-#: bp-templates/bp-legacy/buddypress-functions.php:919
-#: bp-themes/bp-default/_inc/ajax.php:582
+#: bp-templates/bp-legacy/buddypress/groups/single/invites-loop.php:51
+#: bp-templates/bp-legacy/buddypress-functions.php:1031
+#: bp-themes/bp-default/_inc/ajax.php:598
 #: bp-themes/bp-default/groups/create.php:229
 #: bp-themes/bp-default/groups/single/send-invites.php:42
 msgid "Remove Invite"
 msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/groups/create.php:239
-#: bp-templates/bp-legacy/buddypress/groups/single/send-invites.php:73
 #: bp-themes/bp-default/groups/create.php:246
 #: bp-themes/bp-default/groups/single/send-invites.php:73
 msgid "Once you have built up friend connections you will be able to invite others to your group."
@@ -4949,6 +5790,7 @@ msgstr ""
 #: bp-templates/bp-legacy/buddypress/members/single/profile/change-avatar.php:24
 #: bp-themes/bp-default/groups/single/admin.php:139
 #: bp-themes/bp-default/members/single/profile/change-avatar.php:24
+#: bp-xprofile/bp-xprofile-admin.php:804
 msgid "Delete Avatar"
 msgstr ""
 
@@ -4987,52 +5829,29 @@ msgstr ""
 msgid "Promote to Mod"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:276
-#: bp-themes/bp-default/groups/single/admin.php:276
-msgid "Remove this member"
-msgstr ""
-
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:276
-#: bp-themes/bp-default/groups/single/admin.php:276
-msgid "Remove from group"
-msgstr ""
-
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:290
-#: bp-templates/bp-legacy/buddypress/groups/single/members.php:87
-#: bp-themes/bp-default/groups/single/admin.php:290
-#: bp-themes/bp-default/groups/single/members.php:87
-msgid "This group has no members."
-msgstr ""
-
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:320
-#: bp-templates/bp-legacy/buddypress/members/single/friends/requests.php:37
-#: bp-templates/bp-legacy/buddypress/members/single/groups/invites.php:23
-#: bp-themes/bp-default/groups/single/admin.php:320
-#: bp-themes/bp-default/members/single/friends/requests.php:37
-#: bp-themes/bp-default/members/single/groups/invites.php:23
-msgid "Accept"
+#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:276
+#: bp-themes/bp-default/groups/single/admin.php:276
+msgid "Remove this member"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:322
-#: bp-templates/bp-legacy/buddypress/members/single/friends/requests.php:38
-#: bp-templates/bp-legacy/buddypress/members/single/groups/invites.php:24
-#: bp-themes/bp-default/groups/single/admin.php:322
-#: bp-themes/bp-default/members/single/friends/requests.php:38
-#: bp-themes/bp-default/members/single/groups/invites.php:24
-msgid "Reject"
+#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:276
+#: bp-themes/bp-default/groups/single/admin.php:276
+msgid "Remove from group"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:335
-#: bp-themes/bp-default/groups/single/admin.php:335
-msgid "There are no pending membership requests."
+#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:290
+#: bp-templates/bp-legacy/buddypress/groups/single/members.php:79
+#: bp-themes/bp-default/groups/single/admin.php:290
+#: bp-themes/bp-default/groups/single/members.php:87
+msgid "This group has no members."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:352
+#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:324
 #: bp-themes/bp-default/groups/single/admin.php:352
 msgid "WARNING: Deleting this group will completely remove ALL content associated with it. There is no way back, please be careful with this option."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:355
+#: bp-templates/bp-legacy/buddypress/groups/single/admin.php:327
 #: bp-themes/bp-default/groups/single/admin.php:355
 msgid "I understand the consequences of deleting this group."
 msgstr ""
@@ -5131,6 +5950,29 @@ msgstr ""
 msgid "Send Request"
 msgstr ""
 
+#: bp-templates/bp-legacy/buddypress/groups/single/requests-loop.php:31
+#: bp-templates/bp-legacy/buddypress/members/single/friends/requests.php:37
+#: bp-templates/bp-legacy/buddypress/members/single/groups/invites.php:23
+#: bp-themes/bp-default/groups/single/admin.php:320
+#: bp-themes/bp-default/members/single/friends/requests.php:37
+#: bp-themes/bp-default/members/single/groups/invites.php:23
+msgid "Accept"
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress/groups/single/requests-loop.php:33
+#: bp-templates/bp-legacy/buddypress/members/single/friends/requests.php:38
+#: bp-templates/bp-legacy/buddypress/members/single/groups/invites.php:24
+#: bp-themes/bp-default/groups/single/admin.php:322
+#: bp-themes/bp-default/members/single/friends/requests.php:38
+#: bp-themes/bp-default/members/single/groups/invites.php:24
+msgid "Reject"
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress/groups/single/requests-loop.php:62
+#: bp-themes/bp-default/groups/single/admin.php:335
+msgid "There are no pending membership requests."
+msgstr ""
+
 #: bp-templates/bp-legacy/buddypress/members/activate.php:14
 #: bp-themes/bp-default/registration/activate.php:23
 msgid "Your account was activated successfully! Your account details have been sent to you in a separate email."
@@ -5158,19 +6000,13 @@ msgstr ""
 msgid "Newest Registered"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/members-loop.php:108
-#: bp-themes/bp-default/members/members-loop.php:108
-msgid "Sorry, no members were found."
-msgstr ""
-
 #: bp-templates/bp-legacy/buddypress/members/register.php:13
 #: bp-themes/bp-default/registration/register.php:16
 msgid "User registration is currently not allowed."
 msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/members/register.php:22
-#: bp-themes/bp-default/registration/register.php:27
-msgid "Registering for this site is easy, just fill in the fields below and we'll get a new account set up for you in no time."
+msgid "Registering for this site is easy. Just fill in the fields below, and we'll get a new account set up for you in no time."
 msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/members/register.php:30
@@ -5178,32 +6014,12 @@ msgstr ""
 msgid "Account Details"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:32
-#: bp-themes/bp-default/registration/register.php:37
-#: bp-themes/bp-default/sidebar.php:44
-msgid "Username"
-msgstr ""
-
 #: bp-templates/bp-legacy/buddypress/members/register.php:32
 #: bp-templates/bp-legacy/buddypress/members/register.php:36
 #: bp-templates/bp-legacy/buddypress/members/register.php:40
 #: bp-templates/bp-legacy/buddypress/members/register.php:44
-#: bp-templates/bp-legacy/buddypress/members/register.php:71
-#: bp-templates/bp-legacy/buddypress/members/register.php:79
-#: bp-templates/bp-legacy/buddypress/members/register.php:87
-#: bp-templates/bp-legacy/buddypress/members/register.php:97
-#: bp-templates/bp-legacy/buddypress/members/register.php:108
-#: bp-templates/bp-legacy/buddypress/members/register.php:123
-#: bp-templates/bp-legacy/buddypress/members/register.php:134
-#: bp-templates/bp-legacy/buddypress/members/register.php:207
-#: bp-templates/bp-legacy/buddypress/members/register.php:216
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:26
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:33
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:40
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:49
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:67
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:83
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:93
+#: bp-templates/bp-legacy/buddypress/members/register.php:132
+#: bp-templates/bp-legacy/buddypress/members/register.php:141
 #: bp-themes/bp-default/members/single/profile/edit.php:26
 #: bp-themes/bp-default/members/single/profile/edit.php:33
 #: bp-themes/bp-default/members/single/profile/edit.php:40
@@ -5215,15 +6031,23 @@ msgstr ""
 #: bp-themes/bp-default/registration/register.php:41
 #: bp-themes/bp-default/registration/register.php:45
 #: bp-themes/bp-default/registration/register.php:49
-#: bp-themes/bp-default/registration/register.php:76
-#: bp-themes/bp-default/registration/register.php:84
-#: bp-themes/bp-default/registration/register.php:92
-#: bp-themes/bp-default/registration/register.php:102
-#: bp-themes/bp-default/registration/register.php:113
-#: bp-themes/bp-default/registration/register.php:128
-#: bp-themes/bp-default/registration/register.php:139
-#: bp-themes/bp-default/registration/register.php:212
-#: bp-themes/bp-default/registration/register.php:221
+#: bp-themes/bp-default/registration/register.php:78
+#: bp-themes/bp-default/registration/register.php:86
+#: bp-themes/bp-default/registration/register.php:94
+#: bp-themes/bp-default/registration/register.php:104
+#: bp-themes/bp-default/registration/register.php:115
+#: bp-themes/bp-default/registration/register.php:130
+#: bp-themes/bp-default/registration/register.php:141
+#: bp-themes/bp-default/registration/register.php:216
+#: bp-themes/bp-default/registration/register.php:225
+#: bp-xprofile/bp-xprofile-classes.php:1516
+#: bp-xprofile/bp-xprofile-classes.php:1740
+#: bp-xprofile/bp-xprofile-classes.php:1877
+#: bp-xprofile/bp-xprofile-classes.php:2021
+#: bp-xprofile/bp-xprofile-classes.php:2165
+#: bp-xprofile/bp-xprofile-classes.php:2304
+#: bp-xprofile/bp-xprofile-classes.php:2386
+#: bp-xprofile/bp-xprofile-classes.php:2465
 msgid "(required)"
 msgstr ""
 
@@ -5242,77 +6066,68 @@ msgstr ""
 msgid "Confirm Password"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:60
-#: bp-themes/bp-default/registration/register.php:65
+#: bp-templates/bp-legacy/buddypress/members/register.php:62
+#: bp-themes/bp-default/registration/register.php:67
 msgid "Profile Details"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:114
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:58
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:73
-#: bp-themes/bp-default/members/single/profile/edit.php:58
-#: bp-themes/bp-default/members/single/profile/edit.php:73
-#: bp-themes/bp-default/registration/register.php:119
-#: bp-xprofile/bp-xprofile-admin.php:415
-msgid "Clear"
-msgstr ""
-
-#: bp-templates/bp-legacy/buddypress/members/register.php:156
-#: bp-templates/bp-legacy/buddypress/members/register.php:171
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:120
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:134
+#: bp-templates/bp-legacy/buddypress/members/register.php:79
+#: bp-templates/bp-legacy/buddypress/members/register.php:94
+#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:33
+#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:47
 #: bp-themes/bp-default/members/single/profile/edit.php:120
 #: bp-themes/bp-default/members/single/profile/edit.php:134
-#: bp-themes/bp-default/registration/register.php:161
-#: bp-themes/bp-default/registration/register.php:176
+#: bp-themes/bp-default/registration/register.php:163
+#: bp-themes/bp-default/registration/register.php:178
 msgid "This field can be seen by: <span class=\"current-visibility-level\">%s</span>"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:156
-#: bp-themes/bp-default/registration/register.php:161
+#: bp-templates/bp-legacy/buddypress/members/register.php:79
+#: bp-themes/bp-default/registration/register.php:163
 msgctxt "Change profile field visibility level"
 msgid "Change"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:161
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:125
+#: bp-templates/bp-legacy/buddypress/members/register.php:84
+#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:38
 #: bp-themes/bp-default/members/single/profile/edit.php:125
-#: bp-themes/bp-default/registration/register.php:166
+#: bp-themes/bp-default/registration/register.php:168
+#: bp-xprofile/bp-xprofile-admin.php:733
 msgid "Who can see this field?"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:201
-#: bp-themes/bp-default/registration/register.php:206
+#: bp-templates/bp-legacy/buddypress/members/register.php:126
+#: bp-themes/bp-default/registration/register.php:210
 msgid "Blog Details"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:203
-#: bp-themes/bp-default/registration/register.php:208
+#: bp-templates/bp-legacy/buddypress/members/register.php:128
+#: bp-themes/bp-default/registration/register.php:212
 msgid "Yes, I'd like to create a new site"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:207
-#: bp-themes/bp-default/registration/register.php:212
+#: bp-templates/bp-legacy/buddypress/members/register.php:132
+#: bp-themes/bp-default/registration/register.php:216
 msgid "Blog URL"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:216
-#: bp-themes/bp-default/registration/register.php:221
+#: bp-templates/bp-legacy/buddypress/members/register.php:141
+#: bp-themes/bp-default/registration/register.php:225
 msgid "Site Title"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:237
-#: bp-themes/bp-default/registration/register.php:242
+#: bp-templates/bp-legacy/buddypress/members/register.php:164
+#: bp-themes/bp-default/registration/register.php:248
 msgid "Complete Sign Up"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:252
-#: bp-themes/bp-default/registration/register.php:259
+#: bp-templates/bp-legacy/buddypress/members/register.php:179
+#: bp-themes/bp-default/registration/register.php:265
 msgid "You have successfully created your account! To begin using this site you will need to activate your account via the email we have just sent to your address."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/register.php:254
-#: bp-themes/bp-default/registration/register.php:261
+#: bp-templates/bp-legacy/buddypress/members/register.php:181
+#: bp-themes/bp-default/registration/register.php:267
 msgid "You have successfully created your account! Please log in using the username and password you have just created."
 msgstr ""
 
@@ -5321,6 +6136,13 @@ msgstr ""
 msgid "You have no pending friendship requests."
 msgstr ""
 
+#: bp-templates/bp-legacy/buddypress/members/single/groups/invites.php:14
+#: bp-themes/bp-default/members/single/groups/invites.php:14
+msgid "1 member"
+msgid_plural "%d members"
+msgstr[0] ""
+msgstr[1] ""
+
 #: bp-templates/bp-legacy/buddypress/members/single/groups/invites.php:37
 #: bp-themes/bp-default/members/single/groups/invites.php:37
 msgid "You have no outstanding group invites."
@@ -5410,10 +6232,40 @@ msgstr ""
 msgid "Send Reply"
 msgstr ""
 
+#: bp-templates/bp-legacy/buddypress/members/single/notifications/feedback-no-notifications.php:7
+#: bp-themes/bp-default/members/single/notifications/feedback-no-notifications.php:7
+msgid "You have no unread notifications."
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress/members/single/notifications/feedback-no-notifications.php:11
+#: bp-themes/bp-default/members/single/notifications/feedback-no-notifications.php:11
+msgid "This member has no unread notifications."
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress/members/single/notifications/feedback-no-notifications.php:19
+#: bp-themes/bp-default/members/single/notifications/feedback-no-notifications.php:19
+msgid "You have no notifications."
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress/members/single/notifications/feedback-no-notifications.php:23
+#: bp-themes/bp-default/members/single/notifications/feedback-no-notifications.php:23
+msgid "This member has no notifications."
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php:5
+#: bp-themes/bp-default/members/single/notifications/notifications-loop.php:5
+msgid "Notification"
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php:6
+#: bp-themes/bp-default/members/single/notifications/notifications-loop.php:6
+msgid "Date Received"
+msgstr ""
+
 #: bp-templates/bp-legacy/buddypress/members/single/profile/change-avatar.php:1
 #: bp-themes/bp-default/members/single/profile/change-avatar.php:1
-#: bp-xprofile/bp-xprofile-loader.php:196
-#: bp-xprofile/bp-xprofile-loader.php:253
+#: bp-xprofile/bp-xprofile-loader.php:205
+#: bp-xprofile/bp-xprofile-loader.php:280
 msgid "Change Avatar"
 msgstr ""
 
@@ -5452,8 +6304,9 @@ msgstr ""
 msgid "Editing '%s' Profile Group"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:120
+#: bp-templates/bp-legacy/buddypress/members/single/profile/edit.php:33
 #: bp-themes/bp-default/members/single/profile/edit.php:120
+#: bp-xprofile/bp-xprofile-admin.php:726
 msgid "Change"
 msgstr ""
 
@@ -5519,132 +6372,148 @@ msgstr ""
 
 #: bp-templates/bp-legacy/buddypress/members/single/settings/notifications.php:4
 #: bp-themes/bp-default/members/single/settings/notifications.php:54
-msgid "Send a notification by email when:"
+msgid "Send an email notice when:"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:63
-msgid "BuddyPress Legacy"
+#: bp-templates/bp-legacy/buddypress/members/single/settings/profile.php:15
+#: bp-themes/bp-default/members/single/settings/profile.php:65
+msgid "Visibility"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:229
-#: bp-themes/bp-default/functions.php:158
-msgid "My Favorites"
+#: bp-templates/bp-legacy/buddypress-functions.php:63
+msgid "BuddyPress Legacy"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:230
+#: bp-templates/bp-legacy/buddypress-functions.php:236
 #: bp-themes/bp-default/functions.php:159
 msgid "Accepted"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:231
-#: bp-themes/bp-default/functions.php:160
-msgid "Rejected"
+#: bp-templates/bp-legacy/buddypress-functions.php:238
+#: bp-themes/bp-default/functions.php:164
+msgid "comments"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:232
-#: bp-themes/bp-default/functions.php:161
-msgid "Show all comments for this thread"
+#: bp-templates/bp-legacy/buddypress-functions.php:239
+msgid "Are you sure you want to leave this group?"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:233
-#: bp-themes/bp-default/functions.php:162
-msgid "Show all %d comments"
+#: bp-templates/bp-legacy/buddypress-functions.php:241
+#: bp-themes/bp-default/functions.php:158
+msgid "My Favorites"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:234
+#: bp-templates/bp-legacy/buddypress-functions.php:242
+#: bp-themes/bp-default/functions.php:160
+msgid "Rejected"
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress-functions.php:244
 #: bp-themes/bp-default/functions.php:163
 msgid "Show all"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:235
-#: bp-themes/bp-default/functions.php:164
-msgid "comments"
+#: bp-templates/bp-legacy/buddypress-functions.php:245
+#: bp-themes/bp-default/functions.php:161
+msgid "Show all comments for this thread"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:240
+#: bp-templates/bp-legacy/buddypress-functions.php:246
+#: bp-themes/bp-default/functions.php:162
+msgid "Show all %d comments"
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress-functions.php:247
 #: bp-themes/bp-default/functions.php:169
 msgid "Your profile has unsaved changes. If you leave the page, the changes will be lost."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:636
+#: bp-templates/bp-legacy/buddypress-functions.php:707
 #: bp-themes/bp-default/_inc/ajax.php:291
 msgid "There was a problem posting your update, please try again."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:730
-#: bp-templates/bp-legacy/buddypress-functions.php:766
+#: bp-templates/bp-legacy/buddypress-functions.php:825
+#: bp-templates/bp-legacy/buddypress-functions.php:861
 #: bp-themes/bp-default/_inc/ajax.php:393
 #: bp-themes/bp-default/_inc/ajax.php:429
 msgid "There was a problem when deleting. Please try again."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:965
-#: bp-themes/bp-default/_inc/ajax.php:627
+#: bp-templates/bp-legacy/buddypress-functions.php:1035
+#: bp-themes/bp-default/_inc/ajax.php:602
+msgid "%s has previously requested to join this group. Sending an invitation will automatically add the member to the group."
+msgstr ""
+
+#: bp-templates/bp-legacy/buddypress-functions.php:1090
+#: bp-themes/bp-default/_inc/ajax.php:656
 msgid " Friendship could not be requested."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:977
-#: bp-themes/bp-default/_inc/ajax.php:639
+#: bp-templates/bp-legacy/buddypress-functions.php:1102
+#: bp-themes/bp-default/_inc/ajax.php:668
 msgid "Friendship request could not be cancelled."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:982
-#: bp-themes/bp-default/_inc/ajax.php:644
+#: bp-templates/bp-legacy/buddypress-functions.php:1107
+#: bp-themes/bp-default/_inc/ajax.php:673
 msgid "Request Pending"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1002
-#: bp-themes/bp-default/_inc/ajax.php:664
+#: bp-templates/bp-legacy/buddypress-functions.php:1127
+#: bp-themes/bp-default/_inc/ajax.php:693
 msgid "There was a problem accepting that request. Please try again."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1021
-#: bp-themes/bp-default/_inc/ajax.php:683
+#: bp-templates/bp-legacy/buddypress-functions.php:1146
+#: bp-themes/bp-default/_inc/ajax.php:712
 msgid "There was a problem rejecting that request. Please try again."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1051
-#: bp-themes/bp-default/_inc/ajax.php:713
+#: bp-templates/bp-legacy/buddypress-functions.php:1176
+#: bp-themes/bp-default/_inc/ajax.php:742
 msgid "Error joining group"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1060
-#: bp-themes/bp-default/_inc/ajax.php:722
+#: bp-templates/bp-legacy/buddypress-functions.php:1189
+#: bp-templates/bp-legacy/buddypress-functions.php:1199
+#: bp-themes/bp-default/_inc/ajax.php:755
+#: bp-themes/bp-default/_inc/ajax.php:765
 msgid "Error requesting membership"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1062
-#: bp-themes/bp-default/_inc/ajax.php:724
+#: bp-templates/bp-legacy/buddypress-functions.php:1201
+#: bp-themes/bp-default/_inc/ajax.php:767
 msgid "Membership Requested"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1070
-#: bp-themes/bp-default/_inc/ajax.php:732
+#: bp-templates/bp-legacy/buddypress-functions.php:1210
+#: bp-themes/bp-default/_inc/ajax.php:776
 msgid "Error leaving group"
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1093
-#: bp-themes/bp-default/_inc/ajax.php:755
+#: bp-templates/bp-legacy/buddypress-functions.php:1233
+#: bp-themes/bp-default/_inc/ajax.php:799
 msgid "There was a problem closing the notice."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1156
-#: bp-themes/bp-default/_inc/ajax.php:806
+#: bp-templates/bp-legacy/buddypress-functions.php:1296
+#: bp-themes/bp-default/_inc/ajax.php:850
 msgid "There was a problem sending that reply. Please try again."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1174
-#: bp-themes/bp-default/_inc/ajax.php:824
+#: bp-templates/bp-legacy/buddypress-functions.php:1314
+#: bp-themes/bp-default/_inc/ajax.php:868
 msgid "There was a problem marking messages as unread."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1199
-#: bp-themes/bp-default/_inc/ajax.php:849
+#: bp-templates/bp-legacy/buddypress-functions.php:1339
+#: bp-themes/bp-default/_inc/ajax.php:893
 msgid "There was a problem marking messages as read."
 msgstr ""
 
-#: bp-templates/bp-legacy/buddypress-functions.php:1224
-#: bp-themes/bp-default/_inc/ajax.php:874
+#: bp-templates/bp-legacy/buddypress-functions.php:1364
+#: bp-themes/bp-default/_inc/ajax.php:918
 msgid "There was a problem deleting messages."
 msgstr ""
 
@@ -5844,10 +6713,6 @@ msgstr ""
 msgid "Theme activated! This theme contains <a href=\"%s\">custom header image</a> support and <a href=\"%s\">sidebar widgets</a>."
 msgstr ""
 
-#: bp-themes/bp-default/functions.php:645
-msgid "Email"
-msgstr ""
-
 #: bp-themes/bp-default/functions.php:655
 msgid "You must be <a href=\"%1$s\">logged in</a> to post a comment."
 msgstr ""
@@ -5895,6 +6760,15 @@ msgstr ""
 msgid "Members Directory"
 msgstr ""
 
+#: bp-themes/bp-default/members/single/profile/edit.php:58
+#: bp-themes/bp-default/members/single/profile/edit.php:73
+#: bp-themes/bp-default/registration/register.php:121
+#: bp-xprofile/bp-xprofile-classes.php:1881
+#: bp-xprofile/bp-xprofile-classes.php:1950
+#: bp-xprofile/bp-xprofile-classes.php:2027
+msgid "Clear"
+msgstr ""
+
 #: bp-themes/bp-default/members/single/settings/general.php:49
 msgid "General Settings"
 msgstr ""
@@ -5911,6 +6785,10 @@ msgstr ""
 msgid "Edit this page."
 msgstr ""
 
+#: bp-themes/bp-default/registration/register.php:27
+msgid "Registering for this site is easy, just fill in the fields below and we'll get a new account set up for you in no time."
+msgstr ""
+
 #: bp-themes/bp-default/search.php:10
 msgid "Site"
 msgstr ""
@@ -5927,15 +6805,7 @@ msgstr ""
 msgid "Please <a href=\"%s\" title=\"Create an account\">create an account</a> to get started."
 msgstr ""
 
-#: bp-themes/bp-default/sidebar.php:47
-msgid "Password"
-msgstr ""
-
-#: bp-themes/bp-default/sidebar.php:50
-msgid "Remember Me"
-msgstr ""
-
-#: bp-themes/bp-default/sidebar.php:66
+#: bp-themes/bp-default/sidebar.php:65
 msgid "Forum Topic Tags"
 msgstr ""
 
@@ -5953,27 +6823,43 @@ msgstr ""
 msgid "Sorry, no posts matched your criteria."
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-activity.php:20
+#: bp-xprofile/bp-xprofile-activity.php:26
 msgid "Member changed profile picture"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-activity.php:21
+#: bp-xprofile/bp-xprofile-activity.php:33
 msgid "New member registered"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-activity.php:22
+#: bp-xprofile/bp-xprofile-activity.php:40
 msgid "Updated Profile"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-activity.php:129
+#: bp-xprofile/bp-xprofile-activity.php:59
+#: tests/testcases/xprofile/activity.php:285
 msgid "%s changed their profile picture"
 msgstr ""
 
+#: bp-xprofile/bp-xprofile-activity.php:80
+#: tests/testcases/xprofile/activity.php:307
+#: tests/testcases/xprofile/activity.php:333
+msgid "%s became a registered member"
+msgstr ""
+
+#: bp-xprofile/bp-xprofile-activity.php:105
+#: tests/testcases/xprofile/activity.php:356
+msgid "%s&#8217;s profile was updated"
+msgstr ""
+
+#: bp-xprofile/bp-xprofile-activity.php:312
+msgid "Profile Updates"
+msgstr ""
+
 #: bp-xprofile/bp-xprofile-admin.php:27 bp-xprofile/bp-xprofile-admin.php:71
 msgid "Profile Fields"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-admin.php:72 bp-xprofile/bp-xprofile-classes.php:354
+#: bp-xprofile/bp-xprofile-admin.php:72 bp-xprofile/bp-xprofile-classes.php:454
 msgid "Add New Field Group"
 msgstr ""
 
@@ -6045,244 +6931,286 @@ msgstr ""
 msgid "(Required)"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:271
-msgid "Please make sure you give the group a name."
+#: bp-xprofile/bp-xprofile-admin.php:436
+msgctxt "xprofile field type category"
+msgid "Other"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:356
-msgid "Create Field Group"
+#: bp-xprofile/bp-xprofile-admin.php:559
+msgctxt "xprofile user-admin edit screen"
+msgid "User marked as a spammer"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:358
-msgid "Edit Field Group"
+#: bp-xprofile/bp-xprofile-admin.php:563
+msgctxt "xprofile user-admin edit screen"
+msgid "Avatar"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:384
-msgid "Field Group Title"
+#: bp-xprofile/bp-xprofile-admin.php:723
+msgid "This field can be seen by: <span class=\"%s\">%s</span>"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:391
-msgid "Group Description"
+#: bp-xprofile/bp-xprofile-classes.php:366
+msgid "Please make sure you give the group a name."
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:752
-msgid "Please enter options for this Field:"
+#: bp-xprofile/bp-xprofile-classes.php:456
+msgid "Create Field Group"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:754
-msgid "Sort Order:"
+#: bp-xprofile/bp-xprofile-classes.php:458
+msgid "Edit Field Group"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:756
-msgid "Custom"
+#: bp-xprofile/bp-xprofile-classes.php:484
+#: bp-xprofile/bp-xprofile-classes.php:485
+msgid "Field Group Title"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:757
-msgid "Ascending"
+#: bp-xprofile/bp-xprofile-classes.php:491
+msgid "Group Description"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:758
-msgid "Descending"
+#: bp-xprofile/bp-xprofile-classes.php:837
+msgid "Add Field"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:786
-#: bp-xprofile/bp-xprofile-classes.php:803
-msgid "Default Value"
+#: bp-xprofile/bp-xprofile-classes.php:849
+msgid "Edit Field"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:810
-msgid "Add Another Option"
+#: bp-xprofile/bp-xprofile-classes.php:873
+msgid "Field Description"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:818
-msgid "Add Field"
+#: bp-xprofile/bp-xprofile-classes.php:882
+msgid "Submit"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:830
-msgid "Edit Field"
+#: bp-xprofile/bp-xprofile-classes.php:904
+msgid "Default Visibility"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:837
-msgid "Fields marked * are required"
+#: bp-xprofile/bp-xprofile-classes.php:922
+msgid "Per-Member Visibility"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:850
-msgid "Field Title"
+#: bp-xprofile/bp-xprofile-classes.php:927
+msgid "Let members change this field's visibility"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:857
-msgid "Field Description"
+#: bp-xprofile/bp-xprofile-classes.php:931
+msgid "Enforce the default visibility for all members"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:866
-msgid "Is This Field Required?"
+#: bp-xprofile/bp-xprofile-classes.php:946
+msgid "Field Requirement"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:868
+#: bp-xprofile/bp-xprofile-classes.php:949
 msgid "Not Required"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:869
+#: bp-xprofile/bp-xprofile-classes.php:950
 msgid "Required"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:874
+#: bp-xprofile/bp-xprofile-classes.php:956
 msgid "Field Type"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:876
-msgid "Text Box"
+#: bp-xprofile/bp-xprofile-classes.php:994
+msgid "Please make sure you fill out all required fields."
+msgstr ""
+
+#: bp-xprofile/bp-xprofile-classes.php:1002
+msgid "This field type require at least one option. Please add options below."
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:877
-msgid "Multi-line Text Box"
+#: bp-xprofile/bp-xprofile-classes.php:1466
+#: bp-xprofile/bp-xprofile-classes.php:2274
+#: bp-xprofile/bp-xprofile-classes.php:2356
+#: bp-xprofile/bp-xprofile-classes.php:2435
+msgctxt "xprofile field type category"
+msgid "Single Fields"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:878
+#: bp-xprofile/bp-xprofile-classes.php:1467
+msgctxt "xprofile field type"
 msgid "Date Selector"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:879
-msgid "Radio Buttons"
+#: bp-xprofile/bp-xprofile-classes.php:1604
+msgid "January"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:880
-msgid "Drop Down Select Box"
+#: bp-xprofile/bp-xprofile-classes.php:1605
+msgid "February"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:881
-msgid "Multi Select Box"
+#: bp-xprofile/bp-xprofile-classes.php:1606
+msgid "March"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:882
-msgid "Checkboxes"
+#: bp-xprofile/bp-xprofile-classes.php:1607
+msgid "April"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:902
-msgid "Default Visibility"
+#: bp-xprofile/bp-xprofile-classes.php:1608
+msgid "May"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:915
-msgid "Per-Member Visibility"
+#: bp-xprofile/bp-xprofile-classes.php:1609
+msgid "June"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:917
-msgid "Let members change this field's visibility"
+#: bp-xprofile/bp-xprofile-classes.php:1610
+msgid "July"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:918
-msgid "Enforce the default visibility for all members"
+#: bp-xprofile/bp-xprofile-classes.php:1611
+msgid "August"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:928
-msgid "or"
+#: bp-xprofile/bp-xprofile-classes.php:1612
+msgid "September"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:946
-msgid "Please make sure you fill out all required fields."
+#: bp-xprofile/bp-xprofile-classes.php:1613
+msgid "October"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:949
-msgid "Radio button field types require at least one option. Please add options below."
+#: bp-xprofile/bp-xprofile-classes.php:1614
+msgid "November"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:952
-#: bp-xprofile/bp-xprofile-classes.php:955
-msgid "Select box field types require at least one option. Please add options below."
+#: bp-xprofile/bp-xprofile-classes.php:1615
+msgid "December"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-classes.php:958
-msgid "Checkbox field types require at least one option. Please add options below."
+#: bp-xprofile/bp-xprofile-classes.php:1710
+#: bp-xprofile/bp-xprofile-classes.php:1849
+#: bp-xprofile/bp-xprofile-classes.php:1984
+#: bp-xprofile/bp-xprofile-classes.php:2137
+msgctxt "xprofile field type category"
+msgid "Multi Fields"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-loader.php:106
-msgid "Anyone"
+#: bp-xprofile/bp-xprofile-classes.php:1711
+msgctxt "xprofile field type"
+msgid "Checkboxes"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-loader.php:110
-msgid "Logged In Users"
+#: bp-xprofile/bp-xprofile-classes.php:1850
+msgctxt "xprofile field type"
+msgid "Radio Buttons"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-loader.php:114
-msgid "Admins Only"
+#: bp-xprofile/bp-xprofile-classes.php:1985
+msgctxt "xprofile field type"
+msgid "Multi Select Box"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-screens.php:96
-msgid "Please make sure you fill in all required fields in this profile field group before saving."
+#: bp-xprofile/bp-xprofile-classes.php:2138
+msgctxt "xprofile field type"
+msgid "Drop Down Select Box"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-screens.php:129
-msgid "There was a problem updating some of your profile information, please try again."
+#: bp-xprofile/bp-xprofile-classes.php:2275
+msgctxt "xprofile field type"
+msgid "Multi-line Text Area"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-screens.php:131
-msgid "Changes saved."
+#: bp-xprofile/bp-xprofile-classes.php:2357
+msgctxt "xprofile field type"
+msgid "Text Box"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-screens.php:199
-msgid "There was a problem cropping your avatar."
+#: bp-xprofile/bp-xprofile-classes.php:2436
+msgctxt "xprofile field type"
+msgid "Number"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-screens.php:201
-msgid "Your new avatar was uploaded successfully."
+#: bp-xprofile/bp-xprofile-classes.php:2713
+msgid "Please enter options for this Field:"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:681
-msgid "January"
+#: bp-xprofile/bp-xprofile-classes.php:2716
+msgid "Sort Order:"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:682
-msgid "February"
+#: bp-xprofile/bp-xprofile-classes.php:2718
+msgid "Custom"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:683
-msgid "March"
+#: bp-xprofile/bp-xprofile-classes.php:2719
+msgid "Ascending"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:684
-msgid "April"
+#: bp-xprofile/bp-xprofile-classes.php:2720
+msgid "Descending"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:685
-msgid "May"
+#: bp-xprofile/bp-xprofile-classes.php:2781
+msgid "Default Value"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:686
-msgid "June"
+#: bp-xprofile/bp-xprofile-classes.php:2789
+msgid "Add Another Option"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:687
-msgid "July"
+#: bp-xprofile/bp-xprofile-loader.php:107
+msgid "Everyone"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:688
-msgid "August"
+#: bp-xprofile/bp-xprofile-loader.php:111
+msgid "Only Me"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:689
-msgid "September"
+#: bp-xprofile/bp-xprofile-loader.php:115
+msgid "All Members"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:690
-msgid "October"
+#: bp-xprofile/bp-xprofile-screens.php:140
+msgid "Changes saved."
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:691
-msgid "November"
+#: bp-xprofile/bp-xprofile-screens.php:208
+msgid "There was a problem cropping your avatar."
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:692
-msgid "December"
+#: bp-xprofile/bp-xprofile-screens.php:211
+msgid "Your new avatar was uploaded successfully."
+msgstr ""
+
+#: bp-xprofile/bp-xprofile-settings.php:43
+msgid "Your profile settings have been saved."
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:875
+#: bp-xprofile/bp-xprofile-settings.php:47
+msgid "This member's profile settings have been saved."
+msgstr ""
+
+#: bp-xprofile/bp-xprofile-template.php:636
 msgid "Avatar uploads are currently disabled. Why not use a <a href=\"http://gravatar.com\" target=\"_blank\">gravatar</a> instead?"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:883
+#: bp-xprofile/bp-xprofile-template.php:644
 msgid "Profile not recently updated"
 msgstr ""
 
-#: bp-xprofile/bp-xprofile-template.php:893
+#: bp-xprofile/bp-xprofile-template.php:654
 msgid "Profile updated %s"
+msgstr ""
+
+#: bp-xprofile/bp-xprofile-template.php:804
+msgid "This field's visibility cannot be changed."
+msgstr ""
+
+#: tests/testcases/groups/activity.php:25
+msgid "%s created the group %s"
+msgstr ""
+
+#: tests/testcases/groups/activity.php:47
+msgid "%s joined the group %s"
 msgstr ""
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-loader.php b/wp-content/plugins/buddypress/bp-loader.php
index d8d009a8fcb7681bc036abb2fb763878720496c6..2a3dbdcaab1449747ba023e5286a9ef26b0364b4 100644
--- a/wp-content/plugins/buddypress/bp-loader.php
+++ b/wp-content/plugins/buddypress/bp-loader.php
@@ -16,7 +16,7 @@
  * Description: Social networking in a box. Build a social network for your company, school, sports team or niche community all based on the power and flexibility of WordPress.
  * Author:      The BuddyPress Community
  * Author URI:  http://buddypress.org/community/members/
- * Version:     1.8.1
+ * Version:     2.0
  * Text Domain: buddypress
  * Domain Path: /bp-languages/
  * License:     GPLv2 or later (license.txt)
@@ -33,182 +33,186 @@ if ( !class_exists( 'BuddyPress' ) ) :
  *
  * Tap tap tap... Is this thing on?
  *
- * @since BuddyPress (1.6)
+ * @since BuddyPress (1.6.0)
  */
 class BuddyPress {
 
-	/** Magic *****************************************************************/
+	/** Magic *************************************************************/
 
 	/**
-	 * BuddyPress uses many variables, most of which can be filtered to customize
-	 * the way that it works. To prevent unauthorized access, these variables
-	 * are stored in a private array that is magically updated using PHP 5.2+
-	 * methods. This is to prevent third party plugins from tampering with
-	 * essential information indirectly, which would cause issues later.
+	 * BuddyPress uses many variables, most of which can be filtered to
+	 * customize the way that it works. To prevent unauthorized access,
+	 * these variables are stored in a private array that is magically
+	 * updated using PHP 5.2+ methods. This is to prevent third party
+	 * plugins from tampering with essential information indirectly, which
+	 * would cause issues later.
 	 *
 	 * @see BuddyPress::setup_globals()
 	 * @var array
 	 */
 	private $data;
 
-	/** Not Magic *************************************************************/
+	/** Not Magic *********************************************************/
 
 	/**
-	 * @var array Primary BuddyPress navigation
+	 * @var array Primary BuddyPress navigation.
 	 */
 	public $bp_nav = array();
 
 	/**
-	 * @var array Secondary BuddyPress navigation to $bp_nav
+	 * @var array Secondary BuddyPress navigation to $bp_nav.
 	 */
 	public $bp_options_nav = array();
 
 	/**
-	 * @var array The unfiltered URI broken down into chunks
+	 * @var array The unfiltered URI broken down into chunks.
 	 * @see bp_core_set_uri_globals()
 	 */
 	public $unfiltered_uri = array();
 
 	/**
-	 * @var array The canonical URI stack
+	 * @var array The canonical URI stack.
 	 * @see bp_redirect_canonical()
 	 * @see bp_core_new_nav_item()
 	 */
 	public $canonical_stack = array();
 
 	/**
-	 * @var array Additional navigation elements (supplemental)
+	 * @var array Additional navigation elements (supplemental).
 	 */
 	public $action_variables = array();
 
 	/**
-	 * @var array Required components (core, members)
+	 * @var array Required components (core, members).
 	 */
 	public $required_components = array();
 
 	/**
-	 * @var array Additional active components
+	 * @var array Additional active components.
 	 */
 	public $loaded_components = array();
 
 	/**
-	 * @var array Active components
+	 * @var array Active components.
 	 */
 	public $active_components = array();
 
-	/** Option Overload *******************************************************/
+	/** Option Overload ***************************************************/
 
 	/**
-	 * @var array Optional Overloads default options retrieved from get_option()
+	 * @var array Optional Overloads default options retrieved from get_option().
 	 */
 	public $options = array();
 
-	/** Singleton *************************************************************/
+	/** Singleton *********************************************************/
 
 	/**
-	 * @var BuddyPress The one true BuddyPress
-	 */
-	private static $instance;
-
-	/**
-	 * Main BuddyPress Instance
+	 * Main BuddyPress Instance.
 	 *
 	 * BuddyPress is great
 	 * Please load it only one time
 	 * For this, we thank you
 	 *
-	 * Insures that only one instance of BuddyPress exists in memory at any one
-	 * time. Also prevents needing to define globals all over the place.
+	 * Insures that only one instance of BuddyPress exists in memory at any
+	 * one time. Also prevents needing to define globals all over the place.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 *
-	 * @staticvar array $instance
-	 * @uses BuddyPress::constants() Setup the constants (mostly deprecated)
-	 * @uses BuddyPress::setup_globals() Setup the globals needed
-	 * @uses BuddyPress::includes() Include the required files
-	 * @uses BuddyPress::setup_actions() Setup the hooks and actions
+	 * @static object $instance
+	 * @uses BuddyPress::constants() Setup the constants (mostly deprecated).
+	 * @uses BuddyPress::setup_globals() Setup the globals needed.
+	 * @uses BuddyPress::legacy_constants() Setup the legacy constants (deprecated).
+	 * @uses BuddyPress::includes() Include the required files.
+	 * @uses BuddyPress::setup_actions() Setup the hooks and actions.
 	 * @see buddypress()
 	 *
-	 * @return BuddyPress The one true BuddyPress
+	 * @return BuddyPress The one true BuddyPress.
 	 */
 	public static function instance() {
-		if ( ! isset( self::$instance ) ) {
-			self::$instance = new BuddyPress;
-			self::$instance->constants();
-			self::$instance->setup_globals();
-			self::$instance->legacy_constants();
-			self::$instance->includes();
-			self::$instance->setup_actions();
+
+		// Store the instance locally to avoid private static replication
+		static $instance = null;
+
+		// Only run these methods if they haven't been run previously
+		if ( null === $instance ) {
+			$instance = new BuddyPress;
+			$instance->constants();
+			$instance->setup_globals();
+			$instance->legacy_constants();
+			$instance->includes();
+			$instance->setup_actions();
 		}
-		return self::$instance;
+
+		// Always return the instance
+		return $instance;
 	}
 
-	/** Magic Methods *********************************************************/
+	/** Magic Methods *****************************************************/
 
 	/**
 	 * A dummy constructor to prevent BuddyPress from being loaded more than once.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 * @see BuddyPress::instance()
 	 * @see buddypress()
 	 */
 	private function __construct() { /* Do nothing here */ }
 
 	/**
-	 * A dummy magic method to prevent BuddyPress from being cloned
+	 * A dummy magic method to prevent BuddyPress from being cloned.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __clone() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'buddypress' ), '1.7' ); }
 
 	/**
-	 * A dummy magic method to prevent BuddyPress from being unserialized
+	 * A dummy magic method to prevent BuddyPress from being unserialized.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __wakeup() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'buddypress' ), '1.7' ); }
 
 	/**
-	 * Magic method for checking the existence of a certain custom field
+	 * Magic method for checking the existence of a certain custom field.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __isset( $key ) { return isset( $this->data[$key] ); }
 
 	/**
-	 * Magic method for getting BuddyPress varibles
+	 * Magic method for getting BuddyPress varibles.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __get( $key ) { return isset( $this->data[$key] ) ? $this->data[$key] : null; }
 
 	/**
-	 * Magic method for setting BuddyPress varibles
+	 * Magic method for setting BuddyPress varibles.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __set( $key, $value ) { $this->data[$key] = $value; }
 
 	/**
-	 * Magic method for unsetting BuddyPress variables
+	 * Magic method for unsetting BuddyPress variables.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __unset( $key ) { if ( isset( $this->data[$key] ) ) unset( $this->data[$key] ); }
 
 	/**
-	 * Magic method to prevent notices and errors from invalid method calls
+	 * Magic method to prevent notices and errors from invalid method calls.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function __call( $name = '', $args = array() ) { unset( $name, $args ); return null; }
 
-	/** Private Methods *******************************************************/
+	/** Private Methods ***************************************************/
 
 	/**
-	 * Bootstrap constants
+	 * Bootstrap constants.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 *
 	 * @uses is_multisite()
 	 * @uses get_current_site()
@@ -225,7 +229,7 @@ class BuddyPress {
 
 		// Path and URL
 		if ( ! defined( 'BP_PLUGIN_DIR' ) ) {
-			define( 'BP_PLUGIN_DIR', trailingslashit( WP_PLUGIN_DIR . '/buddypress' ) );
+			define( 'BP_PLUGIN_DIR', trailingslashit( plugin_dir_path( __FILE__ ) ) );
 		}
 
 		if ( ! defined( 'BP_PLUGIN_URL' ) ) {
@@ -272,6 +276,11 @@ class BuddyPress {
 			define( 'BP_ROOT_BLOG', $root_blog_id );
 		}
 
+		// Whether to refrain from loading deprecated functions
+		if ( ! defined( 'BP_IGNORE_DEPRECATED' ) ) {
+			define( 'BP_IGNORE_DEPRECATED', false );
+		}
+
 		// The search slug has to be defined nice and early because of the way
 		// search requests are loaded
 		//
@@ -281,37 +290,37 @@ class BuddyPress {
 	}
 
 	/**
-	 * Component global variables
+	 * Component global variables.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 * @access private
 	 *
-	 * @uses plugin_dir_path() To generate BuddyPress plugin path
-	 * @uses plugin_dir_url() To generate BuddyPress plugin url
-	 * @uses apply_filters() Calls various filters
+	 * @uses plugin_dir_path() To generate BuddyPress plugin path.
+	 * @uses plugin_dir_url() To generate BuddyPress plugin url.
+	 * @uses apply_filters() Calls various filters.
 	 */
 	private function setup_globals() {
 
-		/** Versions **********************************************************/
+		/** Versions **************************************************/
 
-		$this->version    = '1.8.1';
-		$this->db_version = 6080;
+		$this->version    = '2.0';
+		$this->db_version = 7892;
 
-		/** Loading ***********************************************************/
+		/** Loading ***************************************************/
 
-		$this->load_deprecated  = true;
+		$this->load_deprecated = ! apply_filters( 'bp_ignore_deprecated', BP_IGNORE_DEPRECATED );
 
-		/** Toolbar ***********************************************************/
+		/** Toolbar ***************************************************/
 
 		/**
 		 * @var string The primary toolbar ID
 		 */
 		$this->my_account_menu_id = '';
 
-		/** URI's *************************************************************/
+		/** URIs ******************************************************/
 
 		/**
-		 * @var int The current offset of the URI
+		 * @var int The current offset of the URI.
 		 * @see bp_core_set_uri_globals()
 		 */
 		$this->unfiltered_uri_offset = 0;
@@ -321,7 +330,7 @@ class BuddyPress {
 		 */
 		$this->no_status_set = false;
 
-		/** Components ********************************************************/
+		/** Components ************************************************/
 
 		/**
 		 * @var string Name of the current BuddyPress component (primary)
@@ -343,12 +352,12 @@ class BuddyPress {
 		 */
 		$this->is_single_item = false;
 
-		/** Root **************************************************************/
+		/** Root ******************************************************/
 
 		// BuddyPress Root blog ID
 		$this->root_blog_id = (int) apply_filters( 'bp_get_root_blog_id', BP_ROOT_BLOG );
 
-		/** Paths *************************************************************/
+		/** Paths******************************************************/
 
 		// BuddyPress root directory
 		$this->file           = __FILE__;
@@ -367,24 +376,24 @@ class BuddyPress {
 		$this->old_themes_dir = $this->plugin_dir . 'bp-themes';
 		$this->old_themes_url = $this->plugin_url . 'bp-themes';
 
-		/** Theme Compat ******************************************************/
+		/** Theme Compat **********************************************/
 
 		$this->theme_compat   = new stdClass(); // Base theme compatibility class
 		$this->filters        = new stdClass(); // Used when adding/removing filters
 
-		/** Users *************************************************************/
+		/** Users *****************************************************/
 
 		$this->current_user   = new stdClass();
 		$this->displayed_user = new stdClass();
 	}
 
 	/**
-	 * Legacy BuddyPress constants
+	 * Legacy BuddyPress constants.
 	 *
 	 * Try to avoid using these. Their values have been moved into variables
 	 * in the instance, and have matching functions to get/set their values.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	private function legacy_constants() {
 
@@ -396,22 +405,22 @@ class BuddyPress {
 	}
 
 	/**
-	 * Include required files
+	 * Include required files.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 * @access private
 	 *
-	 * @uses is_admin() If in WordPress admin, load additional file
+	 * @uses is_admin() If in WordPress admin, load additional file.
 	 */
 	private function includes() {
 
 		// Load the WP abstraction file so BuddyPress can run on all WordPress setups.
-		require( BP_PLUGIN_DIR . '/bp-core/bp-core-wpabstraction.php' );
+		require( $this->plugin_dir . '/bp-core/bp-core-wpabstraction.php' );
 
 		// Setup the versions (after we include multisite abstraction above)
 		$this->versions();
 
-		/** Update/Install ****************************************************/
+		/** Update/Install ********************************************/
 
 		// Theme compatability
 		require( $this->plugin_dir . 'bp-core/bp-core-template-loader.php'     );
@@ -444,18 +453,19 @@ class BuddyPress {
 			require( $this->plugin_dir . 'bp-core/deprecated/1.5.php' );
 			require( $this->plugin_dir . 'bp-core/deprecated/1.6.php' );
 			require( $this->plugin_dir . 'bp-core/deprecated/1.7.php' );
+			require( $this->plugin_dir . 'bp-core/deprecated/2.0.php' );
 		}
 	}
 
 	/**
-	 * Setup the default hooks and actions
+	 * Set up the default hooks and actions.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 * @access private
 	 *
-	 * @uses register_activation_hook() To register the activation hook
-	 * @uses register_deactivation_hook() To register the deactivation hook
-	 * @uses add_action() To add various actions
+	 * @uses register_activation_hook() To register the activation hook.
+	 * @uses register_deactivation_hook() To register the deactivation hook.
+	 * @uses add_action() To add various actions.
 	 */
 	private function setup_actions() {
 
@@ -491,9 +501,9 @@ class BuddyPress {
 	}
 
 	/**
-	 * Private method to align the active and database versions
+	 * Private method to align the active and database versions.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	private function versions() {
 
@@ -518,26 +528,38 @@ class BuddyPress {
 		}
 	}
 
-	/** Public Methods ********************************************************/
+	/** Public Methods ****************************************************/
 
 	/**
-	 * Setup the BuddyPress theme directory
+	 * Set up BuddyPress's legacy theme directory.
+	 *
+	 * Starting with version 1.2, and ending with version 1.8, BuddyPress
+	 * registered a custom theme directory - bp-themes - which contained
+	 * the bp-default theme. Since BuddyPress 1.9, bp-themes is no longer
+	 * registered (and bp-default no longer offered) on new installations.
+	 * Sites using bp-default (or a child theme of bp-default) will
+	 * continue to have bp-themes registered as before.
+	 *
+	 * @since BuddyPress (1.5.0)
 	 *
-	 * @since BuddyPress (1.5)
-	 * @todo Move bp-default to wordpress.org/extend/themes and remove this
+	 * @todo Move bp-default to wordpress.org/extend/themes and remove this.
 	 */
 	public function register_theme_directory() {
+		if ( ! bp_do_register_theme_directory() ) {
+			return;
+		}
+
 		register_theme_directory( $this->old_themes_dir );
 	}
 
 	/**
-	 * Register bundled theme packages
+	 * Register bundled theme packages.
 	 *
 	 * Note that since we currently have complete control over bp-themes and
 	 * the bp-legacy folders, it's fine to hardcode these here. If at a
 	 * later date we need to automate this, an API will need to be built.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function register_theme_packages() {
 
@@ -557,9 +579,9 @@ class BuddyPress {
 	}
 
 	/**
-	 * Setup the default BuddyPress theme compatability location.
+	 * Set up the default BuddyPress theme compatability location.
 	 *
-	 * @since BuddyPress (1.7)
+	 * @since BuddyPress (1.7.0)
 	 */
 	public function setup_theme() {
 
@@ -573,22 +595,21 @@ class BuddyPress {
 }
 
 /**
- * The main function responsible for returning the one true BuddyPress Instance
- * to functions everywhere.
+ * The main function responsible for returning the one true BuddyPress Instance to functions everywhere.
  *
  * Use this function like you would a global variable, except without needing
  * to declare the global.
  *
  * Example: <?php $bp = buddypress(); ?>
  *
- * @return BuddyPress The one true BuddyPress Instance
+ * @return BuddyPress The one true BuddyPress Instance.
  */
 function buddypress() {
 	return BuddyPress::instance();
 }
 
 /**
- * Hook BuddyPress early onto the 'plugins_loaded' action.
+ * Hook BuddyPress early onto the 'plugins_loaded' action..
  *
  * This gives all other plugins the chance to load before BuddyPress, to get
  * their actions, filters, and overrides setup without BuddyPress being in the
@@ -599,7 +620,7 @@ if ( defined( 'BUDDYPRESS_LATE_LOAD' ) ) {
 
 // "And now here's something we hope you'll really like!"
 } else {
-	$GLOBALS['bp'] = &buddypress();
+	$GLOBALS['bp'] = buddypress();
 }
 
 endif;
diff --git a/wp-content/plugins/buddypress/bp-members/admin/bp-members-classes.php b/wp-content/plugins/buddypress/bp-members/admin/bp-members-classes.php
new file mode 100644
index 0000000000000000000000000000000000000000..70a9ef3de46d6c02a5177e4f1803c253f2253ae1
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-members/admin/bp-members-classes.php
@@ -0,0 +1,666 @@
+<?php
+
+/**
+ * BuddyPress Members List Classes
+ *
+ * @package BuddyPress
+ * @subpackage MembersAdminClasses
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+if ( class_exists( 'WP_Users_List_Table') ) :
+
+/**
+ * List table class for signups admin page.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_Members_List_Table extends WP_Users_List_Table {
+
+	/**
+	 * Signup counts.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $signup_counts = 0;
+
+	/**
+	 * Constructor.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function __construct() {
+		// Define singular and plural labels, as well as whether we support AJAX.
+		parent::__construct( array(
+			'ajax'     => false,
+			'plural'   => 'signups',
+			'singular' => 'signup',
+		) );
+	}
+
+	/**
+	 * Set up items for display in the list table.
+	 *
+	 * Handles filtering of data, sorting, pagination, and any other data
+	 * manipulation required prior to rendering.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function prepare_items() {
+		global $usersearch;
+
+		$usersearch = isset( $_REQUEST['s'] ) ? $_REQUEST['s'] : '';
+
+		$signups_per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) );
+
+		$paged = $this->get_pagenum();
+
+		$args = array(
+			'offset'     => ( $paged - 1 ) * $signups_per_page,
+			'number'     => $signups_per_page,
+			'usersearch' => $usersearch,
+			'orderby'    => 'signup_id',
+			'order'      => 'DESC'
+		);
+
+		if ( isset( $_REQUEST['orderby'] ) ) {
+			$args['orderby'] = $_REQUEST['orderby'];
+		}
+
+		if ( isset( $_REQUEST['order'] ) ) {
+			$args['order'] = $_REQUEST['order'];
+		}
+
+		$signups = BP_Signup::get( $args );
+
+		$this->items = $signups['signups'];
+		$this->signup_counts = $signups['total'];
+
+		$this->set_pagination_args( array(
+			'total_items' => $this->signup_counts,
+			'per_page'    => $signups_per_page,
+		) );
+	}
+
+	/**
+	 * Get the views (the links above the WP List Table).
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @uses WP_Users_List_Table::get_views() to get the users views
+	 */
+	public function get_views() {
+		$views = parent::get_views();
+
+		// Remove the 'current' class from the 'All' link
+		$views['all']        = str_replace( 'class="current"', '', $views['all'] );
+		$views['registered'] = '<a href="' . add_query_arg( 'page', 'bp-signups', bp_get_admin_url( 'users.php' ) ) . '"  class="current">' . sprintf( _x( 'Pending <span class="count">(%s)</span>', 'signup users', 'buddypress' ), number_format_i18n( $this->signup_counts ) ) . '</a>';
+
+		return $views;
+	}
+
+	/**
+	 * Get rid of the extra nav.
+	 *
+	 * WP_Users_List_Table will add an extra nav to change user's role.
+	 * As we're dealing with signups, we don't need this.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function extra_tablenav( $which ) {
+		return;
+	}
+
+	/**
+	 * Specific signups columns
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function get_columns() {
+		return apply_filters( 'bp_members_signup_columns', array(
+			'cb'         => '<input type="checkbox" />',
+			'username'   => __( 'Username', 'buddypress' ),
+			'name'       => __( 'Name', 'buddypress' ),
+			'email'      => __( 'Email', 'buddypress' ),
+			'registered' => __( 'Registered', 'buddypress' ),
+			'date_sent'  => __( 'Last Sent', 'buddypress' ),
+			'count_sent' => __( '# Times Emailed', 'buddypress' )
+		) );
+	}
+
+	/**
+	 * Specific bulk actions for signups.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function get_bulk_actions() {
+		$actions = array(
+			'activate' => _x( 'Activate', 'Pending signup action', 'buddypress' ),
+			'resend'   => _x( 'Email', 'Pending signup action', 'buddypress' ),
+		);
+
+		if ( current_user_can( 'delete_users' ) ) {
+			$actions['delete'] = __( 'Delete', 'buddypress' );
+		}
+
+		return $actions;
+	}
+
+	/**
+	 * The text shown when no items are found.
+	 *
+	 * Nice job, clean sheet!
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function no_items() {
+
+		if ( bp_get_signup_allowed() ) {
+			esc_html_e( 'No pending accounts found.', 'buddypress' );
+		} else {
+			$link = false;
+
+			// Specific case when BuddyPress is not network activated
+			if ( is_multisite() && current_user_can( 'manage_network_users') ) {
+				$link = '<a href="' . esc_url( network_admin_url( 'settings.php' ) ) . '">' . esc_html__( 'Edit settings', 'buddypress' ) . '</a>';
+			} elseif ( current_user_can( 'manage_options' ) ) {
+				$link = '<a href="' . esc_url( bp_get_admin_url( 'options-general.php' ) ) . '">' . esc_html__( 'Edit settings', 'buddypress' ) . '</a>';
+			}
+			
+			printf( __( 'Registration is disabled. %s', 'buddypress' ), $link );
+		}
+			
+	}
+
+	/**
+	 * The columns signups can be reordered with.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function get_sortable_columns() {
+		return array(
+			'username'   => 'login',
+			'email'      => 'email',
+			'registered' => 'signup_id',
+		);
+	}
+
+	/**
+	 * Display signups rows.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function display_rows() {
+		$style = '';
+		foreach ( $this->items as $userid => $signup_object ) {
+			$style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"';
+			echo "\n\t" . $this->single_row( $signup_object, $style );
+		}
+	}
+
+	/**
+	 * Display a signup row.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @see WP_List_Table::single_row() for explanation of params.
+	 */
+	public function single_row( $signup_object = null, $style = '', $role = '', $numposts = 0 ) {
+		echo '<tr' . $style . ' id="signup-' . esc_attr( $signup_object->id ) . '">';
+		echo $this->single_row_columns( $signup_object );
+		echo '</tr>';
+	}
+
+	/**
+	 * Markup for the checkbox used to select items for bulk actions.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function column_cb( $signup_object = null ) {
+		?>
+		<label class="screen-reader-text" for="signup_<?php echo intval( $signup_object->id ); ?>"><?php echo esc_html( sprintf( __( 'Select %s', 'buddypress' ), $signup_object->user_login ) ); ?></label>
+		<input type="checkbox" id="signup_<?php echo intval( $signup_object->id ) ?>" name="allsignups[]" value="<?php echo esc_attr( $signup_object->id ) ?>" />
+		<?php
+	}
+
+	/**
+	 * The row actions (delete/activate/email).
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_username( $signup_object = null ) {
+		$avatar	= get_avatar( $signup_object->user_email, 32 );
+
+		// Activation email link
+		$email_link = add_query_arg(
+			array(
+				'page'	    => 'bp-signups',
+				'signup_id' => $signup_object->id,
+				'action'    => 'resend',
+			),
+			bp_get_admin_url( 'users.php' )
+		);
+
+		// Activate link
+		$activate_link = add_query_arg(
+			array(
+				'page'      => 'bp-signups',
+				'signup_id' => $signup_object->id,
+				'action'    => 'activate',
+			),
+			bp_get_admin_url( 'users.php' )
+		);
+
+		// Delete link
+		$delete_link = add_query_arg(
+			array(
+				'page'      => 'bp-signups',
+				'signup_id' => $signup_object->id,
+				'action'    => 'delete',
+			),
+			bp_get_admin_url( 'users.php' )
+		);
+
+		echo $avatar . '<strong><a href="' . $activate_link .'" class="edit" title="' . esc_attr__( 'Activate', 'buddypress' ) . '">' . $signup_object->user_login .'</a></strong><br/>';
+
+		$actions = array();
+
+		$actions['activate'] = '<a href="' . esc_url( $activate_link ) . '">' . __( 'Activate', 'buddypress' ) . '</a>';
+
+		$actions['resend'] = '<a href="' . esc_url( $email_link ) . '">' . __( 'Email', 'buddypress' ) . '</a>';
+
+		if ( current_user_can( 'delete_users' ) ) {
+			$actions['delete'] = '<a href="' . esc_url( $delete_link ) . '" class="delete">' . __( 'Delete', 'buddypress' ) . '</a>';
+		}
+
+		$actions = apply_filters( 'bp_members_ms_signup_row_actions', $actions, $signup_object );
+		echo $this->row_actions( $actions );
+	}
+
+	/**
+	 * Display user name, if any.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_name( $signup_object = null ) {
+		echo esc_html( $signup_object->user_name );
+	}
+
+	/**
+	 * Display user email.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_email( $signup_object = null ) {
+		echo '<a href="mailto:' . esc_attr( $signup_object->user_email ) . '">' . esc_html( $signup_object->user_email ) .'</a>';
+	}
+
+	/**
+	 * Display registration date.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_registered( $signup_object = null ) {
+		echo mysql2date( 'Y/m/d', $signup_object->registered );
+	}
+
+	/**
+	 * Display the last time an activation email has been sent.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_date_sent( $signup_object = null ) {
+		echo mysql2date( 'Y/m/d', $signup_object->date_sent );
+	}
+
+	/**
+	 * Display number of time an activation email has been sent.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function column_count_sent( $signup_object = null ) {
+		echo absint( $signup_object->count_sent );
+	}
+}
+
+endif;
+
+if ( class_exists( 'WP_MS_Users_List_Table' ) ) :
+/**
+ * List table class for signups network admin page.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
+
+	/**
+	 * Signup counts.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @access public
+	 * @var int
+	 */
+	public $signup_counts = 0;
+
+	/**
+	 * Constructor
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function __construct() {
+		// Define singular and plural labels, as well as whether we support AJAX.
+		parent::__construct( array(
+			'ajax'     => false,
+			'plural'   => 'signups',
+			'singular' => 'signup',
+		) );
+	}
+
+	/**
+	 * Set up items for display in the list table.
+	 *
+	 * Handles filtering of data, sorting, pagination, and any other data
+	 * manipulation required prior to rendering.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function prepare_items() {
+		global $usersearch, $wpdb, $mode;
+
+		$usersearch = isset( $_REQUEST['s'] ) ? $_REQUEST['s'] : '';
+
+		$signups_per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) );
+
+		$paged = $this->get_pagenum();
+
+		$args = array(
+			'offset'     => ( $paged - 1 ) * $signups_per_page,
+			'number'     => $signups_per_page,
+			'usersearch' => $usersearch,
+			'orderby'    => 'signup_id',
+			'order'      => 'DESC'
+		);
+
+		if ( isset( $_REQUEST['orderby'] ) )
+			$args['orderby'] = $_REQUEST['orderby'];
+
+		if ( isset( $_REQUEST['order'] ) )
+			$args['order'] = $_REQUEST['order'];
+
+		$mode = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode'];
+
+		$signups = BP_Signup::get( $args );
+
+		$this->items = $signups['signups'];
+		$this->signup_counts = $signups['total'];
+
+		$this->set_pagination_args( array(
+			'total_items' => $this->signup_counts,
+			'per_page'    => $signups_per_page,
+		) );
+	}
+
+	/**
+	 * Get the views : the links above the WP List Table.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @uses WP_MS_Users_List_Table::get_views() to get the users views
+	 */
+	function get_views() {
+		$views = parent::get_views();
+
+		$views['all'] = str_replace( 'class="current"', '', $views['all'] );
+			$class = ' class="current"';
+
+		$views['registered'] = '<a href="' . add_query_arg( 'page', 'bp-signups', bp_get_admin_url( 'users.php' ) ) . '"  class="current">' . sprintf( _x( 'Pending <span class="count">(%s)</span>', 'signup users', 'buddypress' ), number_format_i18n( $this->signup_counts ) ) . '</a>';
+
+		return $views;
+	}
+
+	/**
+	 * Specific signups columns
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function get_columns() {
+		return apply_filters( 'bp_members_ms_signup_columns', array(
+			'cb'         => '<input type="checkbox" />',
+			'username'   => __( 'Username', 'buddypress' ),
+			'name'       => __( 'Name', 'buddypress' ),
+			'email'      => __( 'Email', 'buddypress' ),
+			'registered' => __( 'Registered', 'buddypress' ),
+			'date_sent'  => __( 'Last Sent', 'buddypress' ),
+			'count_sent' => __( '# Times Emailed', 'buddypress' )
+		) );
+	}
+
+	/**
+	 * Specific bulk actions for signups
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function get_bulk_actions() {
+		$actions = array(
+			'activate' => _x( 'Activate', 'Pending signup action', 'buddypress' ),
+			'resend'   => _x( 'Email', 'Pending signup action', 'buddypress' ),
+		);
+
+		if ( current_user_can( 'delete_users' ) ) {
+			$actions['delete'] = __( 'Delete', 'buddypress' );
+		}
+
+		return $actions;
+	}
+
+	/**
+	 * The text shown when no items are found.
+	 *
+	 * Nice job, clean sheet!
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function no_items() {
+		if ( bp_get_signup_allowed() ) {
+			esc_html_e( 'No pending accounts found.', 'buddypress' );
+		} else {
+			$link = false;
+
+			if ( current_user_can( 'manage_network_users' ) ) {
+				$link = '<a href="' . esc_url( network_admin_url( 'settings.php' ) ) . '">' . esc_html__( 'Edit settings', 'buddypress' ) . '</a>';
+			}
+
+			printf( __( 'Registration is disabled. %s', 'buddypress' ), $link );
+		}
+	}
+
+	/**
+	 * The columns signups can be reordered with
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function get_sortable_columns() {
+		return array(
+			'username'   => 'login',
+			'email'      => 'email',
+			'registered' => 'signup_id',
+		);
+	}
+
+	/**
+	 * Display signups rows.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function display_rows() {
+		$style = '';
+		foreach ( $this->items as $userid => $signup_object ) {
+			$style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"';
+			echo "\n\t" . $this->single_row( $signup_object, $style );
+		}
+	}
+
+	/**
+	 * Display a signup row.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @see WP_List_Table::single_row() for explanation of params.
+	 */
+	public function single_row( $signup_object = null, $style = '' ) {
+		echo '<tr' . $style . ' id="signup-' . esc_attr( $signup_object->id ) . '">';
+		echo $this->single_row_columns( $signup_object );
+		echo '</tr>';
+	}
+
+	/**
+	 * Markup for the checkbox used to select items for bulk actions.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function column_cb( $signup_object = null ) {
+		?>
+		<label class="screen-reader-text" for="signup_<?php echo intval( $signup_object->id ); ?>"><?php echo esc_html( sprintf( __( 'Select %s', 'buddypress' ), $signup_object->user_login ) ); ?></label>
+		<input type="checkbox" id="signup_<?php echo intval( $signup_object->id ) ?>" name="allsignups[]" value="<?php echo esc_attr( $signup_object->id ) ?>" />
+		<?php
+	}
+
+	/**
+	 * The row actions (delete/activate/email).
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_username( $signup_object = null ) {
+		$avatar	= get_avatar( $signup_object->user_email, 32 );
+
+		// Activation email link
+		$email_link = add_query_arg(
+			array(
+				'page'	    => 'bp-signups',
+				'signup_id' => $signup_object->id,
+				'action'    => 'resend',
+			),
+			bp_get_admin_url( 'users.php' )
+		);
+
+		// Activate link
+		$activate_link = add_query_arg(
+			array(
+				'page'      => 'bp-signups',
+				'signup_id' => $signup_object->id,
+				'action'    => 'activate',
+			),
+			bp_get_admin_url( 'users.php' )
+		);
+
+		// Delete link
+		$delete_link = add_query_arg(
+			array(
+				'page'      => 'bp-signups',
+				'signup_id' => $signup_object->id,
+				'action'    => 'delete',
+			),
+			bp_get_admin_url( 'users.php' )
+		);
+
+		echo $avatar . '<strong><a href="' . esc_url( $activate_link ) .'" class="edit" title="' . esc_attr__( 'Activate', 'buddypress' ) . '">' . $signup_object->user_login .'</a></strong><br/>';
+
+		$actions['activate'] = '<a href="' . esc_url( $activate_link ) . '">' . __( 'Activate', 'buddypress' ) . '</a>';
+
+		$actions['resend'] = '<a href="' . esc_url( $email_link ) . '">' . __( 'Email', 'buddypress' ) . '</a>';
+
+		if ( current_user_can( 'delete_users' ) ) {
+			$actions['delete'] = '<a href="' . esc_url( $delete_link ) . '" class="delete">' . __( 'Delete', 'buddypress' ) . '</a>';
+		}
+
+		$actions = apply_filters( 'bp_members_ms_signup_row_actions', $actions, $signup_object );
+		echo $this->row_actions( $actions );
+	}
+
+	/**
+	 * Display user name, if any.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_name( $signup_object = null ) {
+		echo esc_html( $signup_object->user_name );
+	}
+
+	/**
+	 * Display user email.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_email( $signup_object = null ) {
+		echo '<a href="mailto:' . esc_attr( $signup_object->user_email ) . '">' . esc_html( $signup_object->user_email ) .'</a>';
+	}
+
+	/**
+	 * Display registration date
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param object $signup_object The signup data object.
+	 */
+	public function column_registered( $signup_object = null ) {
+		global $mode;
+
+		if ( 'list' == $mode ) {
+			$date = 'Y/m/d';
+		} else {
+			$date = 'Y/m/d \<\b\r \/\> g:i:s a';
+		}
+
+		echo mysql2date( $date, $signup_object->registered ) . "</td>";
+	}
+
+	/**
+	 * Display the last time an activation email has been sent.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function column_date_sent( $signup_object = null ) {
+		global $mode;
+
+		if ( 'list' == $mode ) {
+			$date = 'Y/m/d';
+		} else {
+			$date = 'Y/m/d \<\b\r \/\> g:i:s a';
+		}
+
+		echo mysql2date( $date, $signup_object->date_sent );
+	}
+
+	/**
+	 * Display number of time an activation email has been sent.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function column_count_sent( $signup_object = null ) {
+		echo absint( $signup_object->count_sent );
+	}
+}
+
+endif;
diff --git a/wp-content/plugins/buddypress/bp-members/admin/css/admin.css b/wp-content/plugins/buddypress/bp-members/admin/css/admin.css
new file mode 100644
index 0000000000000000000000000000000000000000..b0a0e1f85d95a6a11f4f518a5bef206c2a07fa9c
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-members/admin/css/admin.css
@@ -0,0 +1,179 @@
+/**** BP Members Profile Administration Screens ****/
+
+div#profile-page.wrap form#your-profile {
+	position:relative;
+}
+
+div#profile-page.wrap form#your-profile h3:first-of-type {
+	margin-top:6em;
+}
+
+div#profile-page.wrap form#your-profile ul#profile-nav {
+	position:absolute;
+	top:-6em;
+	border-bottom:solid 1px #ccc;
+	width:100%;
+}
+
+div#community-profile-page ul#profile-nav {
+	border-bottom:solid 1px #ccc;
+	width:100%;
+	margin-top:1em;
+	margin-bottom:1em;
+	padding:1em 0;
+	padding-bottom: 0;
+	height:2.4em;
+}
+
+form#your-profile ul#profile-nav li,
+div#community-profile-page ul#profile-nav li {
+	margin-left:0.4em;
+	float:left;
+	font-weight: bold;
+	font-size: 15px;
+	line-height: 24px;
+}
+
+form#your-profile ul#profile-nav li a,
+div#community-profile-page ul#profile-nav li a {
+	text-decoration: none;
+	color:#888;
+}
+
+form#your-profile ul#profile-nav li a:hover,
+form#your-profile ul#profile-nav li.nav-tab-active a,
+div#community-profile-page ul#profile-nav li a:hover,
+div#community-profile-page ul#profile-nav li.nav-tab-active a {
+	text-decoration: none;
+	color:#000;
+}
+
+div#community-profile-page li.bp-members-profile-stats:before,
+div#community-profile-page li.bp-friends-profile-stats:before,
+div#community-profile-page li.bp-groups-profile-stats:before,
+div#community-profile-page li.bp-blogs-profile-stats:before,
+div#community-profile-page a.bp-xprofile-avatar-user-admin:before {
+	font-family: 'dashicons';
+	font-size: 18px;
+	vertical-align: bottom;
+	margin-right:5px;
+}
+
+div#community-profile-page li.bp-members-profile-stats:before {
+	content: "\f130";
+}
+
+div#community-profile-page li.bp-friends-profile-stats:before {
+	content: "\f454";
+}
+
+div#community-profile-page li.bp-groups-profile-stats:before {
+	content: "\f456";
+}
+
+div#community-profile-page li.bp-blogs-profile-stats:before {
+	content: "\f120";
+}
+
+div#community-profile-page a.bp-xprofile-avatar-user-admin:before {
+	content:"\f182";
+}
+
+div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar {
+	width:150px;
+	margin:0 auto;
+}
+
+div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar img {
+	max-width: 100%;
+	height: auto;
+}
+
+div#community-profile-page div#bp_xprofile_user_admin_avatar a {
+	display:block;
+	margin:1em 0;
+	text-decoration:none;
+	color:#888;
+}
+
+div#community-profile-page p.not-activated {
+	margin:1em 1em 0;
+	color:red;
+}
+
+#community-profile-page #submitdiv #publishing-action {
+	float: none;
+	width: 100%;
+}
+
+.bp-view-profile {
+	float: left;
+}
+
+.alt {
+	background: none;
+}
+.bp-profile-field {
+	border-bottom: dotted 1px #ccc;
+	font-size: 14px;
+	margin: 15px 0;
+	padding: 10px;
+}
+.bp-profile-field:last-child {
+	border-bottom: 0;
+}
+.bp-profile-field p {
+	font-size: 14px;
+}
+.bp-profile-field .datebox > label,
+.bp-profile-field .radio > label,
+.bp-profile-field > label {  /* label takes on left side 200px */
+	display: inline-block;
+	font-weight: 600;
+	text-align: left;
+	vertical-align: middle;
+	width: 200px;
+}
+
+.field_type_textarea > label,
+.field_type_multiselectbox > label,
+.field_type_radio .radio > label,
+.field_type_checkbox .checkbox > label {  /* these fields are usually pretty tall, so align the label for better consistency */
+	vertical-align: top;
+}
+.bp-profile-field .description {  /* description also sits in the right side column */
+	margin: 10px 0 10px 200px;
+	text-align: left;
+}
+.clear-value {  /* 'clear value' option also sits in the right side column */
+	display: block;
+	font-size: 12px;
+	margin-left: 200px;
+}
+.field_type_checkbox .checkbox > label + label {  /* force checkboxes to new lines, in the right side column */
+	display: block;
+	margin-left: 200px;
+	width: auto;
+}
+.field_type_radio .radio div:not(.field-visibility-settings) label {  /* force radio buttons to new lines */
+	display: block;
+}
+.field_type_radio .radio div:not(.field-visibility-settings) {  /* make the radio buttons sit in the right side column */
+	display: inline-block;
+}
+.field-visibility-settings-notoggle,
+.field-visibility-settings-toggle {  /* visibility settings go in the left column */
+	margin: 10px 0 10px 200px;
+	text-align: left;
+}
+.field-visibility-settings {  /* visibility settings go in the left column */
+	display: none;
+	margin-left: 200px;
+}
+.field-visibility-settings .button {  /* visibility setting close button */
+	margin-bottom: 15px;
+}
+#normal-sortables .field-visibility-settings legend {  /* id required for css selector weight */
+	font-size: 16px;
+	margin-bottom: 10px;
+}
diff --git a/wp-content/plugins/buddypress/bp-members/admin/css/admin.min.css b/wp-content/plugins/buddypress/bp-members/admin/css/admin.min.css
new file mode 100644
index 0000000000000000000000000000000000000000..20b3d41a70174174aec42fe44acc46aa0ddade16
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-members/admin/css/admin.min.css
@@ -0,0 +1 @@
+div#profile-page.wrap form#your-profile{position:relative}div#profile-page.wrap form#your-profile h3:first-of-type{margin-top:6em}div#profile-page.wrap form#your-profile ul#profile-nav{position:absolute;top:-6em;border-bottom:solid 1px #ccc;width:100%}div#community-profile-page ul#profile-nav{border-bottom:solid 1px #ccc;width:100%;margin-top:1em;margin-bottom:1em;padding:1em 0;padding-bottom:0;height:2.4em}form#your-profile ul#profile-nav li,div#community-profile-page ul#profile-nav li{margin-left:.4em;float:left;font-weight:bold;font-size:15px;line-height:24px}form#your-profile ul#profile-nav li a,div#community-profile-page ul#profile-nav li a{text-decoration:none;color:#888}form#your-profile ul#profile-nav li a:hover,form#your-profile ul#profile-nav li.nav-tab-active a,div#community-profile-page ul#profile-nav li a:hover,div#community-profile-page ul#profile-nav li.nav-tab-active a{text-decoration:none;color:#000}div#community-profile-page li.bp-members-profile-stats:before,div#community-profile-page li.bp-friends-profile-stats:before,div#community-profile-page li.bp-groups-profile-stats:before,div#community-profile-page li.bp-blogs-profile-stats:before,div#community-profile-page a.bp-xprofile-avatar-user-admin:before{font-family:'dashicons';font-size:18px;vertical-align:bottom;margin-right:5px}div#community-profile-page li.bp-members-profile-stats:before{content:"\f130"}div#community-profile-page li.bp-friends-profile-stats:before{content:"\f454"}div#community-profile-page li.bp-groups-profile-stats:before{content:"\f456"}div#community-profile-page li.bp-blogs-profile-stats:before{content:"\f120"}div#community-profile-page a.bp-xprofile-avatar-user-admin:before{content:"\f182"}div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar{width:150px;margin:0 auto}div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar img{max-width:100%;height:auto}div#community-profile-page div#bp_xprofile_user_admin_avatar a{display:block;margin:1em 0;text-decoration:none;color:#888}div#community-profile-page p.not-activated{margin:1em 1em 0;color:red}#community-profile-page #submitdiv #publishing-action{float:none;width:100%}.bp-view-profile{float:left}.alt{background:0}.bp-profile-field{border-bottom:dotted 1px #ccc;font-size:14px;margin:15px 0;padding:10px}.bp-profile-field:last-child{border-bottom:0}.bp-profile-field p{font-size:14px}.bp-profile-field .datebox>label,.bp-profile-field .radio>label,.bp-profile-field>label{display:inline-block;font-weight:600;text-align:left;vertical-align:middle;width:200px}.field_type_textarea>label,.field_type_multiselectbox>label,.field_type_radio .radio>label,.field_type_checkbox .checkbox>label{vertical-align:top}.bp-profile-field .description{margin:10px 0 10px 200px;text-align:left}.clear-value{display:block;font-size:12px;margin-left:200px}.field_type_checkbox .checkbox>label+label{display:block;margin-left:200px;width:auto}.field_type_radio .radio div:not(.field-visibility-settings) label{display:block}.field_type_radio .radio div:not(.field-visibility-settings){display:inline-block}.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin:10px 0 10px 200px;text-align:left}.field-visibility-settings{display:none;margin-left:200px}.field-visibility-settings .button{margin-bottom:15px}#normal-sortables .field-visibility-settings legend{font-size:16px;margin-bottom:10px}
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-members/admin/js/admin.js b/wp-content/plugins/buddypress/bp-members/admin/js/admin.js
new file mode 100644
index 0000000000000000000000000000000000000000..a1d2857cae5e73045acc1d4bbca87242b106e4dd
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-members/admin/js/admin.js
@@ -0,0 +1,53 @@
+( function( $ ) {
+	// Profile Visibility Settings
+
+	$( '.visibility-toggle-link' ).on( 'click', function( event ) {
+		event.preventDefault();
+
+		$( this ).parent().hide()
+			.siblings( '.field-visibility-settings' ).show();
+	} );
+
+	$( '.field-visibility-settings-close' ).on( 'click', function( event ) {
+		event.preventDefault();
+
+		var settings_div = $(this).parent(),
+		vis_setting_text = settings_div.find( 'input:checked' ).parent().text();
+
+		settings_div.hide()
+			.siblings( '.field-visibility-settings-toggle' )
+				.children( '.current-visibility-level' ).text( vis_setting_text ).end()
+			.show();
+	} );
+
+} )( jQuery );
+
+
+/**
+ * Deselects any select options or input options for the specified field element.
+ *
+ * @param {String} container HTML ID of the field
+ * @since BuddyPress (1.0.0)
+ */
+function clear( container ) {
+	container = document.getElementById( container );
+	if ( ! container ) {
+		return;
+	}
+
+	var radioButtons = container.getElementsByTagName( 'INPUT' ),
+		options = container.getElementsByTagName( 'OPTION' ),
+		i       = 0;
+
+	if ( radioButtons ) {
+		for ( i = 0; i < radioButtons.length; i++ ) {
+			radioButtons[i].checked = '';
+		}
+	}
+
+	if ( options ) {
+		for ( i = 0; i < options.length; i++ ) {
+			options[i].selected = false;
+		}
+	}
+}
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-members/admin/js/admin.min.js b/wp-content/plugins/buddypress/bp-members/admin/js/admin.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..96b041092a6f03f8b52683c1803488edebbe0cc5
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-members/admin/js/admin.min.js
@@ -0,0 +1 @@
+(function(a){a(".visibility-toggle-link").on("click",function(b){b.preventDefault();a(this).parent().hide().siblings(".field-visibility-settings").show()});a(".field-visibility-settings-close").on("click",function(d){d.preventDefault();var c=a(this).parent(),b=c.find("input:checked").parent().text();c.hide().siblings(".field-visibility-settings-toggle").children(".current-visibility-level").text(b).end().show()})})(jQuery);function clear(a){a=document.getElementById(a);if(!a){return}var d=a.getElementsByTagName("INPUT"),b=a.getElementsByTagName("OPTION"),c=0;if(d){for(c=0;c<d.length;c++){d[c].checked=""}}if(b){for(c=0;c<b.length;c++){b[c].selected=false}}};
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-actions.php b/wp-content/plugins/buddypress/bp-members/bp-members-actions.php
index 69d0fe9bd8bf8add59b703a5475c675e3c06f2ac..b8d770d809dd52d2d96e52f1654dbe4de95d0e1f 100644
--- a/wp-content/plugins/buddypress/bp-members/bp-members-actions.php
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-actions.php
@@ -25,6 +25,12 @@ if ( !defined( 'ABSPATH' ) ) exit;
  */
 function bp_core_action_set_spammer_status( $user_id = 0 ) {
 
+	// Only super admins can currently spam users (but they can't spam
+	// themselves)
+	if ( ! is_super_admin() || bp_is_my_profile() ) {
+		return;
+	}
+
 	// Use displayed user if it's not yourself
 	if ( empty( $user_id ) )
 		$user_id = bp_displayed_user_id();
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-admin.php b/wp-content/plugins/buddypress/bp-members/bp-members-admin.php
new file mode 100644
index 0000000000000000000000000000000000000000..e03c1a1d479aa5e3ba81afe5881e7f9ca54c6116
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-admin.php
@@ -0,0 +1,1434 @@
+<?php
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+if ( !class_exists( 'BP_Members_Admin' ) ) :
+/**
+ * Load Members admin area.
+ *
+ * @package BuddyPress
+ * @subpackage membersAdministration
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_Members_Admin {
+
+	/** Directory *************************************************************/
+
+	/**
+	 * Path to the BP Members Admin directory.
+	 *
+	 * @var string $admin_dir
+	 */
+	public $admin_dir = '';
+
+	/** URLs ******************************************************************/
+
+	/**
+	 * URL to the BP Members Admin directory.
+	 *
+	 * @var string $admin_url
+	 */
+	public $admin_url = '';
+
+	/**
+	 * URL to the BP Members Admin CSS directory.
+	 *
+	 * @var string $css_url
+	 */
+	public $css_url = '';
+
+	/**
+	 * URL to the BP Members Admin JS directory.
+	 *
+	 * @var string
+	 */
+	public $js_url = '';
+
+	/** Other *****************************************************************/
+
+	/**
+	 * Screen id for edit user's profile page.
+	 *
+	 * @access public
+	 * @var string
+	 */
+	public $user_page = '';
+
+	/**
+	 * Setup BP Members Admin.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @uses buddypress() to get BuddyPress main instance
+	 */
+	public static function register_members_admin() {
+		if( ! is_admin() )
+			return;
+
+		$bp = buddypress();
+
+		if( empty( $bp->members->admin ) ) {
+			$bp->members->admin = new self;
+		}
+
+		return $bp->members->admin;
+	}
+
+	/**
+	 * Constructor method.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function __construct() {
+		$this->setup_globals();
+		$this->setup_actions();
+	}
+
+	/**
+	 * Set admin-related globals.
+	 *
+	 * @access private
+	 * @since BuddyPress (2.0.0)
+	 */
+	private function setup_globals() {
+		$bp = buddypress();
+
+		// Paths and URLs
+		$this->admin_dir = trailingslashit( $bp->plugin_dir  . 'bp-members/admin' ); // Admin path
+		$this->admin_url = trailingslashit( $bp->plugin_url  . 'bp-members/admin' ); // Admin URL
+		$this->css_url   = trailingslashit( $this->admin_url . 'css' ); // Admin CSS URL
+		$this->js_url    = trailingslashit( $this->admin_url . 'js'  ); // Admin CSS URL
+
+		// Capability depends on config
+		$this->capability = bp_core_do_network_admin() ? 'manage_network_options' : 'manage_options';
+
+		// The Edit Profile Screen id
+		$this->user_page = '';
+
+		// The screen ids to load specific css for
+		$this->screen_id = array();
+
+		// The stats metabox default position
+		$this->stats_metabox = new StdClass();
+
+		// The WordPress edit user url
+		$this->edit_url = bp_get_admin_url( 'user-edit.php' );
+
+		// BuddyPress edit user's profile url
+		$this->edit_profile_url = add_query_arg( 'page', 'bp-profile-edit', bp_get_admin_url( 'users.php' ) );
+
+		// Data specific to signups
+		$this->users_page   = '';
+		$this->signups_page = '';
+		$this->users_url    = bp_get_admin_url( 'users.php' );
+		$this->users_screen = bp_core_do_network_admin() ? 'users-network' : 'users';
+
+		// Specific config: BuddyPress is not network activated
+		$this->subsite_activated = (bool) is_multisite() && ! bp_is_network_activated();
+
+		// When BuddyPress is not network activated, only Super Admin can moderate signups
+		if ( ! empty( $this->subsite_activated ) ) {
+			$this->capability = 'manage_network_options';
+		}
+	}
+
+	/**
+	 * Set admin-related actions and filters.
+	 *
+	 * @access private
+	 * @since BuddyPress (2.0.0)
+	 */
+	private function setup_actions() {
+
+		/** Extended Profile *****************************************/
+
+		// Add some page specific output to the <head>
+		add_action( 'bp_admin_head',            array( $this, 'admin_head'      ), 999    );
+
+		// Add menu item to all users menu
+		add_action( bp_core_admin_hook(),       array( $this, 'admin_menus'     ),   5    );
+
+		// Enqueue all admin JS and CSS
+		add_action( 'bp_admin_enqueue_scripts', array( $this, 'enqueue_scripts' )         );
+
+		// Create the Profile Navigation (Profile/Extended Profile)
+		add_action( 'edit_user_profile',        array( $this, 'profile_nav'     ),  99, 1 );
+
+		// Add a row action to users listing
+		add_filter( bp_core_do_network_admin() ? 'ms_user_row_actions' : 'user_row_actions', array( $this, 'row_actions' ), 10, 2 );
+
+		/** Signups **************************************************************/
+
+		if ( is_admin() ) {
+			if ( ! is_multisite() ) {
+				add_action( 'pre_user_query', array( $this, 'remove_signups_from_user_query'),  10, 1 );
+			}
+
+			// Reorganise the views navigation in users.php and signups page
+			if ( current_user_can( $this->capability ) ) {
+				add_filter( "views_{$this->users_screen}", array( $this, 'signup_filter_view' ),    10, 1 );
+				add_filter( 'set-screen-option',           array( $this, 'signup_screen_options' ), 10, 3 );
+			}
+		}
+	}
+
+	/**
+	 * Create the All Users > Edit Profile and Signups submenus.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @uses add_users_page() To add the Edit Profile page in Users section.
+	 */
+	public function admin_menus() {
+
+		// Manage user's profile
+		$hooks['user'] = $this->user_page = add_users_page(
+			__( 'Edit Profile',  'buddypress' ),
+			__( 'Edit Profile',  'buddypress' ),
+			'bp_moderate',
+			'bp-profile-edit',
+			array( &$this, 'user_admin' )
+		);
+
+		// Manage signups
+		$hooks['signups'] = $this->signups_page = add_users_page(
+			__( 'Manage Signups',  'buddypress' ),
+			__( 'Manage Signups',  'buddypress' ),
+			$this->capability,
+			'bp-signups',
+			array( &$this, 'signups_admin' )
+		);
+
+		$edit_page = 'user-edit';
+		$this->users_page = 'users';
+
+		if ( bp_core_do_network_admin() ) {
+			$edit_page          .= '-network';
+			$this->users_page   .= '-network';
+			$this->user_page    .= '-network';
+			$this->signups_page .= '-network';
+		}
+
+		$this->screen_id = array( $edit_page, $this->user_page );
+
+		foreach ( $hooks as $key => $hook ) {
+			add_action( "load-$hook", array( $this, $key . '_admin_load' ) );
+		}
+
+		add_action( "admin_head-$this->user_page", array( $this, 'modify_admin_menu_highlight' ) );
+
+	}
+
+	/**
+	 * Highlight the Users menu if on Edit Profile.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function modify_admin_menu_highlight() {
+		global $plugin_page, $submenu_file;
+
+		// Only Show the All users menu
+		if ( $plugin_page = 'bp-profile-edit' ) {
+			$submenu_file = 'users.php';
+		}
+	}
+
+	/**
+	 * Remove the Edit Profile page.
+	 *
+	 * We add these pages in order to integrate with WP's Users panel, but
+	 * we want them to show up as a row action of the WP panel, not as separate
+	 * subnav items under the Users menu.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_head() {
+		// Remove submenu to force using Profile Navigation
+		remove_submenu_page( 'users.php', 'bp-profile-edit' );
+	}
+
+	/** Community Profile ************************************************/
+
+	/**
+	 * Add some specific styling to the Edit User and Edit User's Profile page.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function enqueue_scripts() {
+		if ( ! in_array( get_current_screen()->id, $this->screen_id ) ) {
+			return;
+		}
+
+		$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
+
+		$css = $this->css_url . "admin{$min}.css";
+		$css = apply_filters( 'bp_members_admin_css', $css );
+		wp_enqueue_style( 'bp-members-css', $css, array(), bp_get_version() );
+
+		// Only load javascript for BuddyPress profile
+		if ( get_current_screen()->id == $this->user_page ) {
+			$js = $this->js_url . "admin{$min}.js";
+			$js = apply_filters( 'bp_members_admin_js', $js );
+			wp_enqueue_script( 'bp-members-js', $js, array( 'jquery' ), bp_get_version(), true );
+		}
+
+		// Plugins may want to hook here to load some css/js
+		do_action( 'bp_members_admin_enqueue_scripts', get_current_screen()->id, $this->screen_id );
+	}
+
+	/**
+	 * Create the Profile navigation in Edit User & Edit Profile pages.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function profile_nav( $user = null, $active = 'WordPress' ) {
+
+		if ( empty( $user->ID ) ) {
+			return;
+		}
+
+		// Don't display here if this is not where other BP
+		// administration takes place
+		if ( bp_core_do_network_admin() && ! is_network_admin() ) {
+			return;
+		}
+
+		$query_args = array( 'user_id' => $user->ID );
+
+		if ( ! empty( $_REQUEST['wp_http_referer'] ) ) {
+			$query_args['wp_http_referer'] = urlencode( stripslashes_deep( $_REQUEST['wp_http_referer'] ) );
+		}
+
+		$community_url = add_query_arg( $query_args, $this->edit_profile_url );
+		$wordpress_url = add_query_arg( $query_args, $this->edit_url         );
+
+		$bp_active = false;
+		$wp_active = ' nav-tab-active';
+		if ( 'BuddyPress' === $active ) {
+			$bp_active = ' nav-tab-active';
+			$wp_active = false;
+		} ?>
+
+		<ul id="profile-nav" class="nav-tab-wrapper">
+			<?php
+			/**
+			 * In configs where BuddyPress is not network activated, as regular
+			 * admins do not have the capacity to edit other users, we must add
+			 * this check.
+			 */
+			?>
+			<?php if ( current_user_can( 'edit_user' ) ) :?>
+				<li class="nav-tab<?php echo esc_attr( $wp_active ); ?>"><a href="<?php echo esc_url( $wordpress_url );?>"><?php _e( 'Profile', 'buddypress' ); ?></a></li>
+			<?php endif ;?>
+			<li class="nav-tab<?php echo esc_attr( $bp_active ); ?>"><a href="<?php echo esc_url( $community_url );?>"><?php _e( 'Extended Profile', 'buddypress' ); ?></a></li>
+
+			<?php do_action( 'bp_members_admin_profile_nav', $active, $user ); ?>
+		</ul>
+
+		<?php
+	}
+
+	/**
+	 * Set up the user's profile admin page.
+	 *
+	 * Loaded before the page is rendered, this function does all initial
+	 * setup, including: processing form requests, registering contextual
+	 * help, and setting up screen options.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function user_admin_load() {
+
+		if ( ! $user_id = intval( $_GET['user_id'] ) ) {
+			wp_die( __( 'No users were found', 'buddypress' ) );
+		}
+
+		// only edit others profile
+		if ( get_current_user_id() == $user_id ) {
+			bp_core_redirect( get_edit_user_link( $user_id ) );
+		}
+
+		// Build redirection URL
+		$redirect_to = remove_query_arg( array( 'action', 'error', 'updated', 'spam', 'ham', 'delete_avatar' ), $_SERVER['REQUEST_URI'] );
+		$doaction = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : false;
+
+		if ( ! empty( $_REQUEST['user_status'] ) ) {
+			$spam = ( 'spam' == $_REQUEST['user_status'] ) ? true : false ;
+
+			if ( $spam != bp_is_user_spammer( $user_id ) ) {
+				$doaction = $_REQUEST['user_status'];
+			}
+		}
+
+		// Call an action for plugins to hook in early
+		do_action_ref_array( 'bp_members_admin_load', array( $doaction, $_REQUEST ) );
+
+		// Allowed actions
+		$allowed_actions = apply_filters( 'bp_members_admin_allowed_actions', array( 'update', 'delete_avatar', 'spam', 'ham' ) );
+
+		// Prepare the display of the Community Profile screen
+		if ( ! in_array( $doaction, $allowed_actions ) ) {
+			add_screen_option( 'layout_columns', array( 'default' => 2, 'max' => 2, ) );
+
+			get_current_screen()->add_help_tab( array(
+				'id'      => 'bp-profile-edit-overview',
+				'title'   => __( 'Overview', 'buddypress' ),
+				'content' =>
+				'<p>' . __( 'This is the admin view of a user&#39;s profile.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'In the main column, you can edit the fields of the user&#39;s extended profile.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'In the right-hand column, you can update the user&#39;s status, delete the user&#39;s avatar, and view recent statistics.', 'buddypress' ) . '</p>'
+			) );
+
+			// Help panel - sidebar links
+			get_current_screen()->set_help_sidebar(
+				'<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
+				'<p>' . __( '<a href="http://codex.buddypress.org/buddypress-site-administration/managing-user-profiles/">Managing Profiles</a>', 'buddypress' ) . '</p>' .
+				'<p>' . __( '<a href="http://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
+			);
+
+			// Register metaboxes for the edit screen.
+			add_meta_box( 'submitdiv', _x( 'Status', 'members user-admin edit screen', 'buddypress' ), array( &$this, 'user_admin_status_metabox' ), get_current_screen()->id, 'side', 'core' );
+
+			// In case xprofile is not active
+			$this->stats_metabox->context = 'normal';
+			$this->stats_metabox->priority = 'core';
+
+			/**
+			 * xProfile Hooks to load the profile fields if component is active
+			 * Plugins should not use this hook, please use 'bp_members_admin_user_metaboxes' instead
+			 */
+			do_action_ref_array( 'bp_members_admin_xprofile_metabox', array( $user_id, get_current_screen()->id, $this->stats_metabox ) );
+
+			// If xProfile is inactive, difficult to know what's profile we're on
+			$display_name = false;
+			if ( 'normal' == $this->stats_metabox->context ) {
+				$display_name = ' - ' . esc_html( bp_core_get_user_displayname( $user_id ) );
+			}
+
+			// User Stat metabox
+			add_meta_box( 'bp_members_admin_user_stats',    _x( 'Stats' . $display_name, 'members user-admin edit screen', 'buddypress' ), array( &$this, 'user_admin_stats_metabox' ), get_current_screen()->id, sanitize_key( $this->stats_metabox->context ), sanitize_key( $this->stats_metabox->priority ) );
+
+			// Custom metabox ?
+			do_action( 'bp_members_admin_user_metaboxes' );
+
+			// Enqueue javascripts
+			wp_enqueue_script( 'postbox' );
+			wp_enqueue_script( 'dashboard' );
+
+		// Spam or Ham user
+		} else if ( in_array( $doaction, array( 'spam', 'ham' ) ) ) {
+
+			check_admin_referer( 'edit-bp-profile_' . $user_id );
+
+			if ( bp_core_process_spammer_status( $user_id, $doaction ) ) {
+				$redirect_to = add_query_arg( 'updated', $doaction, $redirect_to );
+			} else {
+				$redirect_to = add_query_arg( 'error', $doaction, $redirect_to );
+			}
+
+			bp_core_redirect( $redirect_to );
+
+		// Update other stuff once above ones are done
+		} else {
+			$this->redirect = $redirect_to;
+
+			do_action_ref_array( 'bp_members_admin_update_user', array( $doaction, $user_id, $_REQUEST, $this->redirect ) );
+
+			bp_core_redirect( $this->redirect );
+		}
+	}
+
+	/**
+	 * Display the user's profile.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function user_admin() {
+
+		if ( ! current_user_can( 'bp_moderate' ) ) {
+			die( '-1' );
+		}
+
+		$user = get_user_to_edit( $_GET['user_id'] );
+
+		// Construct URL for form
+		$form_url        = remove_query_arg( array( 'action', 'error', 'updated', 'spam', 'ham' ), $_SERVER['REQUEST_URI'] );
+		$form_url        = esc_url( add_query_arg( 'action', 'update', $form_url ) );
+		$wp_http_referer = remove_query_arg( array( 'action', 'updated' ), $_REQUEST['wp_http_referer'] );
+
+		// Prepare notice for admin
+		$notice = array();
+
+		if ( ! empty( $_REQUEST['updated'] ) ) {
+			switch ( $_REQUEST['updated'] ) {
+			case 'avatar':
+				$notice = array(
+					'class'   => 'updated',
+					'message' => __( 'Avatar was deleted successfully!', 'buddypress' )
+				);
+				break;
+			case 'ham' :
+				$notice = array(
+					'class'   => 'updated',
+					'message' => __( 'User removed as spammer.', 'buddypress' )
+				);
+				break;
+			case 'spam' :
+				$notice = array(
+					'class'   => 'updated',
+					'message' => __( 'User marked as spammer. Spam users are visible only to site admins.', 'buddypress' )
+				);
+				break;
+			case 1 :
+				$notice = array(
+					'class'   => 'updated',
+					'message' => __( 'Profile updated.', 'buddypress' )
+				);
+				break;
+			}
+		}
+
+		if ( ! empty( $_REQUEST['error'] ) ) {
+			switch ( $_REQUEST['error'] ) {
+			case 'avatar':
+				$notice = array(
+					'class'   => 'error',
+					'message' => __( 'There was a problem deleting that avatar, please try again.', 'buddypress' )
+				);
+				break;
+			case 'ham' :
+				$notice = array(
+					'class'   => 'error',
+					'message' => __( 'User could not be removed as spammer.', 'buddypress' )
+				);
+				break;
+			case 'spam' :
+				$notice = array(
+					'class'   => 'error',
+					'message' => __( 'User could not be marked as spammer.', 'buddypress' )
+				);
+				break;
+			case 1 :
+				$notice = array(
+					'class'   => 'error',
+					'message' => __( 'An error occured while trying to update the profile.', 'buddypress' )
+				);
+				break;
+			case 2:
+				$notice = array(
+					'class'   => 'error',
+					'message' => __( 'Please make sure you fill in all required fields in this profile field group before saving.', 'buddypress' )
+				);
+				break;
+			case 3:
+				$notice = array(
+					'class'   => 'error',
+					'message' => __( 'There was a problem updating some of your profile information, please try again.', 'buddypress' )
+				);
+				break;
+			}
+		}
+
+		if ( ! empty( $notice ) ) :
+			if ( 'updated' === $notice['class'] ) : ?>
+				<div id="message" class="<?php echo esc_attr( $notice['class'] ); ?>">
+			<?php else: ?>
+				<div class="<?php echo esc_attr( $notice['class'] ); ?>">
+			<?php endif; ?>
+				<p><?php echo esc_html( $notice['message'] ); ?></p>
+				<?php if ( !empty( $wp_http_referer ) && ( 'updated' === $notice['class'] ) ) : ?>
+					<p><a href="<?php echo esc_url( $wp_http_referer ); ?>"><?php esc_html_e( '&larr; Back to Users', 'buddypress' ); ?></a></p>
+				<?php endif; ?>
+			</div>
+		<?php endif; ?>
+
+		<div class="wrap"  id="community-profile-page">
+			<?php screen_icon( 'users' ); ?>
+			<h2>
+				<?php
+				_e( 'Edit User', 'buddypress' );
+				if ( current_user_can( 'create_users' ) ) { ?>
+					<a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add New', 'user', 'buddypress' ); ?></a>
+				<?php } elseif ( is_multisite() && current_user_can( 'promote_users' ) ) { ?>
+					<a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add Existing', 'user', 'buddypress' ); ?></a>
+				<?php }
+				?>
+			</h2>
+
+			<?php if ( ! empty( $user ) ) :
+
+				$this->profile_nav( $user, 'BuddyPress' ); ?>
+
+				<form action="<?php echo esc_attr( $form_url ); ?>" id="your-profile" method="post">
+					<div id="poststuff">
+
+						<div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
+							<div id="post-body-content">
+							</div><!-- #post-body-content -->
+
+							<div id="postbox-container-1" class="postbox-container">
+								<?php do_meta_boxes( get_current_screen()->id, 'side', $user ); ?>
+							</div>
+
+							<div id="postbox-container-2" class="postbox-container">
+								<?php do_meta_boxes( get_current_screen()->id, 'normal',   $user ); ?>
+								<?php do_meta_boxes( get_current_screen()->id, 'advanced', $user ); ?>
+							</div>
+						</div><!-- #post-body -->
+
+					</div><!-- #poststuff -->
+
+					<?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
+					<?php wp_nonce_field( 'meta-box-order',  'meta-box-order-nonce', false ); ?>
+					<?php wp_nonce_field( 'edit-bp-profile_' . $user->ID ); ?>
+
+				</form>
+
+			<?php else : ?>
+				<p><?php printf( __( 'No user found with this ID. <a href="%s">Go back and try again</a>.', 'buddypress' ), esc_url( bp_get_admin_url( 'users.php' ) ) ); ?></p>
+			<?php endif; ?>
+
+		</div><!-- .wrap -->
+		<?php
+	}
+
+	/**
+	 * Render the Status metabox for user's profile screen.
+	 *
+	 * Actions are:
+	 * - Update profile fields if xProfile component is active
+	 * - Spam/Unspam user
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param WP_User $user The WP_User object to be edited.
+	 */
+	public function user_admin_status_metabox( $user = null ) {
+
+		// Bail if no user id or if the user has not activated their account yet
+		if ( empty( $user->ID ) ) {
+			return;
+		}
+
+		if ( ( isset( $user->user_status ) && 2 == $user->user_status ) ) {
+			echo '<p class="not-activated">' . esc_html__( 'User account has not yet been activated', 'buddypress' ) . '</p><br/>';
+			return;
+		}
+		?>
+
+		<div class="submitbox" id="submitcomment">
+			<div id="minor-publishing">
+				<div id="misc-publishing-actions">
+					<?php
+					/**
+					 * In configs where BuddyPress is not network activated, regular admins
+					 * cannot mark a user as a spammer on front end. This prevent them to do
+					 * it in backend.
+					 */
+					?>
+					<?php if ( empty( $this->subsite_activated ) || ( ! empty( $this->subsite_activated ) && current_user_can( 'manage_network_users' ) ) ) : ?>
+						<div class="misc-pub-section" id="comment-status-radio">
+							<label class="approved"><input type="radio" name="user_status" value="ham" <?php checked( bp_is_user_spammer( $user->ID ), false ); ?>><?php esc_html_e( 'Active', 'buddypress' ); ?></label><br />
+							<label class="spam"><input type="radio" name="user_status" value="spam" <?php checked( bp_is_user_spammer( $user->ID ), true ); ?>><?php esc_html_e( 'Spammer', 'buddypress' ); ?></label>
+						</div>
+					<?php endif ;?>
+
+					<div class="misc-pub-section curtime misc-pub-section-last">
+						<?php
+						// translators: Publish box date format, see http://php.net/date
+						$datef = __( 'M j, Y @ G:i', 'buddypress' );
+						$date  = date_i18n( $datef, strtotime( $user->user_registered ) );
+						?>
+						<span id="timestamp"><?php printf( __( 'Registered on: <strong>%1$s</strong>', 'buddypress' ), $date ); ?></span>
+					</div>
+				</div> <!-- #misc-publishing-actions -->
+
+				<div class="clear"></div>
+			</div><!-- #minor-publishing -->
+
+			<div id="major-publishing-actions">
+
+				<div id="publishing-action">
+					<a class="button bp-view-profile" href="<?php echo esc_url( bp_core_get_user_domain( $user->ID ) ); ?>" target="_blank"><?php esc_html_e( 'View Profile', 'buddypress' ); ?></a>
+					<?php submit_button( esc_html__( 'Update Profile', 'buddypress' ), 'primary', 'save', false, array( 'tabindex' => '4' ) ); ?>
+				</div>
+				<div class="clear"></div>
+			</div><!-- #major-publishing-actions -->
+
+		</div><!-- #submitcomment -->
+
+		<?php
+	}
+
+	/**
+	 * Render the fallback metabox in case a user has been marked as a spammer.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param WP_User $user The WP_User object to be edited.
+	 */
+	public function user_admin_spammer_metabox( $user = null ) {
+		?>
+		<p><?php printf( __( '%s has been marked as a spammer. All BuddyPress data associated with the user has been removed', 'buddypress' ), esc_html( bp_core_get_user_displayname( $user->ID ) ) ) ;?></p>
+		<?php
+	}
+
+	/**
+	 * Render the Stats metabox to moderate inappropriate images.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param WP_User $user The WP_User object to be edited.
+	 */
+	public function user_admin_stats_metabox( $user = null ) {
+
+		if ( empty( $user->ID ) ) {
+			return;
+		}
+
+		// If account is not activated last activity is the time user registered
+		if ( isset( $user->user_status ) && 2 == $user->user_status ) {
+			$last_active = $user->user_registered;
+
+		// Account is activated, getting user's last activity
+		} else {
+			$last_active = bp_get_user_last_activity( $user->ID );
+		}
+
+		$datef = __( 'M j, Y @ G:i', 'buddypress' );
+		$date  = date_i18n( $datef, strtotime( $last_active ) ); ?>
+
+		<ul>
+			<li class="bp-members-profile-stats"><?php printf( __( 'Last active: <strong>%1$s</strong>', 'buddypress' ), $date ); ?></li>
+
+			<?php
+			// Loading other stats only if user has activated their account
+			if ( empty( $user->user_status ) ) {
+				do_action( 'bp_members_admin_user_stats', array( 'user_id' => $user->ID ), $user );
+			}
+			?>
+		</ul>
+
+		<?php
+	}
+
+	/**
+	 * Add a link to Profile in Users listing row actions.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $actions WordPress row actions (edit, delete).
+	 * @param object $user The object for the user row.
+	 * @return array Merged actions.
+	 */
+	public function row_actions( $actions = '', $user = null ) {
+		// only edit others profile
+		if ( get_current_user_id() == $user->ID ) {
+			return $actions;
+		}
+
+		// Prevent a regular admin to edit a super admin
+		if( in_array( $user->user_login, get_super_admins() ) ) {
+			return $actions;
+		}
+
+		$edit_profile = add_query_arg( array(
+			'user_id'         => $user->ID,
+			'wp_http_referer' => urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ),
+		), $this->edit_profile_url );
+
+		$edit_profile_link = '<a href="' . esc_url( $edit_profile ) . '">' . esc_html__( 'Extended Profile', 'buddypress' ) . '</a>';
+
+		/**
+		 * Check the edit action is available
+		 * and preserve the order edit | profile | remove/delete
+		 */
+		if ( ! empty( $actions['edit'] ) ) {
+			$edit_action = $actions['edit'];
+			unset( $actions['edit'] );
+
+			$new_edit_actions = array(
+				'edit'         => $edit_action,
+				'edit-profile' => $edit_profile_link,
+			);
+		// if not available simply add the edit profile action
+		} else {
+			$new_edit_actions = array( 'edit-profile' => $edit_profile_link );
+		}
+
+		return array_merge( $new_edit_actions, $actions );
+	}
+
+	/** Signups Management ***********************************************/
+
+	/**
+	 * Display the admin preferences about signups pagination.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param  int $value
+	 * @param  string $option
+	 * @param  int $new_value
+	 * @return int the pagination preferences
+	 */
+	public function signup_screen_options( $value = 0, $option = '', $new_value = 0 ) {
+		if ( 'users_page_bp_signups_network_per_page' != $option && 'users_page_bp_signups_per_page' != $option ) {
+			return $value;
+		}
+
+		// Per page
+		$new_value = (int) $new_value;
+		if ( $new_value < 1 || $new_value > 999 ) {
+			return $value;
+		}
+
+		return $new_value;
+	}
+
+	/**
+	 * Make sure no signups will show in users list.
+	 *
+	 * This is needed to handle signups that may have not been activated
+	 * before the 2.0.0 upgrade.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param  WP_User_Query $query The users query.
+	 * @return WP_User_Query The users query without the signups.
+	 */
+	public function remove_signups_from_user_query( $query = null ) {
+		global $wpdb;
+
+		// Bail if this is an ajax request
+		if ( defined( 'DOING_AJAX' ) )
+			return;
+
+		if ( bp_is_update() ) {
+			return;
+		}
+
+		if ( $this->users_page != get_current_screen()->id ) {
+			return;
+		}
+
+		if ( ! empty( $query->query_vars['role'] ) ) {
+			return;
+		}
+
+		$query->query_where .= " AND {$wpdb->users}.user_status != 2";
+	}
+
+	/**
+	 * Filter the WP Users List Table views to include 'bp-signups'.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param  array $views WP List Table views.
+	 * @return array The views with the signup view added.
+	 */
+	public function signup_filter_view( $views = array() ) {
+		$class = '';
+
+		$signups = BP_Signup::count_signups();
+
+		// Remove the 'current' class from All if we're on the signups
+		// view
+		if ( $this->signups_page == get_current_screen()->id ) {
+			$views['all'] = str_replace( 'class="current"', '', $views['all'] );
+			$class = ' class="current"';
+		}
+
+		$views['registered'] = '<a href="' . add_query_arg( 'page', 'bp-signups', bp_get_admin_url( 'users.php' ) ) . '"' . $class . '>' . sprintf( _x( 'Pending <span class="count">(%s)</span>', 'signup users', 'buddypress' ), number_format_i18n( $signups ) ) . '</a>';
+
+		return $views;
+	}
+
+	/**
+	 * Load the Signup WP Users List table.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param  string $class    The name of the class to use.
+	 * @param  string $required The parent class.
+	 * @return WP_List_Table    The List table.
+	 */
+	public static function get_list_table_class( $class = '', $required = '' ) {
+		if ( empty( $class ) ) {
+			return;
+		}
+
+		if ( ! empty( $required ) ) {
+			require_once( ABSPATH . 'wp-admin/includes/class-wp-' . $required . '-list-table.php' );
+			require_once( buddypress()->members->admin->admin_dir . 'bp-members-classes.php'    );
+		}
+
+		return new $class();
+	}
+
+	/**
+	 * Set up the signups admin page.
+	 *
+	 * Loaded before the page is rendered, this function does all initial
+	 * setup, including: processing form requests, registering contextual
+	 * help, and setting up screen options.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @global $bp_members_signup_list_table
+	 */
+	public function signups_admin_load() {
+		global $bp_members_signup_list_table;
+
+		// Build redirection URL
+		$redirect_to = remove_query_arg( array( 'action', 'error', 'updated', 'activated', 'notactivated', 'deleted', 'notdeleted', 'resent', 'notresent', 'do_delete', 'do_resend', 'do_activate', '_wpnonce', 'signup_ids' ), $_SERVER['REQUEST_URI'] );
+		$doaction = bp_admin_list_table_current_bulk_action();
+
+		// Call an action for plugins to hook in early
+		do_action( 'bp_signups_admin_load', $doaction, $_REQUEST );
+
+		// Allowed actions
+		$allowed_actions = apply_filters( 'bp_signups_admin_allowed_actions', array( 'do_delete', 'do_activate', 'do_resend' ) );
+
+		// Prepare the display of the Community Profile screen
+		if ( ! in_array( $doaction, $allowed_actions ) || -1 == $doaction ) {
+
+			if ( bp_core_do_network_admin() ) {
+				$bp_members_signup_list_table = self::get_list_table_class( 'BP_Members_MS_List_Table', 'ms-users' );
+			} else {
+				$bp_members_signup_list_table = self::get_list_table_class( 'BP_Members_List_Table', 'users' );
+			}
+
+			// per_page screen option
+			add_screen_option( 'per_page', array( 'label' => _x( 'Pending Accounts', 'Pending Accounts per page (screen options)', 'buddypress' ) ) );
+
+			get_current_screen()->add_help_tab( array(
+				'id'      => 'bp-signups-overview',
+				'title'   => __( 'Overview', 'buddypress' ),
+				'content' =>
+				'<p>' . __( 'This is the admininistration screen for pending accounts on your site.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'From the screen options, you can customize the displayed columns and the pagination of this screen.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'You can reorder the list of your pending accounts by clicking on the Username, Email or Registered column headers.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'Using the search form, you can find pending accounts more easily. The Username and Email fields will be included in the search.', 'buddypress' ) . '</p>'
+			) );
+
+			get_current_screen()->add_help_tab( array(
+				'id'      => 'bp-signups-actions',
+				'title'   => __( 'Actions', 'buddypress' ),
+				'content' =>
+				'<p>' . __( 'Hovering over a row in the pending accounts list will display action links that allow you to manage pending accounts. You can perform the following actions:', 'buddypress' ) . '</p>' .
+				'<ul><li>' . __( '"Email" takes you to the confirmation screen before being able to send the activation link to the desired pending account. You can only send the activation email once per day.', 'buddypress' ) . '</li>' .
+				'<li>' . __( '"Delete" allows you to delete a pending account from your site. You will be asked to confirm this deletion.', 'buddypress' ) . '</li></ul>' .
+				'<p>' . __( 'By clicking on a Username you will be able to activate a pending account from the confirmation screen.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'Bulk actions allow you to perform these 3 actions for the selected rows.', 'buddypress' ) . '</p>'
+			) );
+
+			// Help panel - sidebar links
+			get_current_screen()->set_help_sidebar(
+				'<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
+				'<p>' . __( '<a href="http://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
+			);
+		} else {
+			if ( ! empty( $_REQUEST['signup_ids' ] ) ) {
+				$signups = wp_parse_id_list( $_REQUEST['signup_ids' ] );
+			}
+
+			// Handle resent activation links
+			if ( 'do_resend' == $doaction ) {
+				// nonce check
+				check_admin_referer( 'signups_resend' );
+
+				$resent = BP_Signup::resend( $signups );
+
+				if ( empty( $resent ) ) {
+					$redirect_to = add_query_arg( 'error', $doaction, $redirect_to );
+				} else {
+					$query_arg = array( 'updated' => 'resent' );
+
+					if ( ! empty( $resent['resent'] ) ) {
+						$query_arg['resent'] = count( $resent['resent'] );
+					}
+
+					if ( ! empty( $resent['errors'] ) ) {
+						$query_arg['notsent'] = count( $resent['errors'] );
+						set_transient( '_bp_admin_signups_errors', $resent['errors'], 30 );
+					}
+
+					$redirect_to = add_query_arg( $query_arg, $redirect_to );
+				}
+
+				bp_core_redirect( $redirect_to );
+
+			// Handle activated accounts
+			} else if ( 'do_activate' == $doaction ) {
+				// nonce check
+				check_admin_referer( 'signups_activate' );
+
+				$activated = BP_Signup::activate( $signups );
+
+				if ( empty( $activated ) ) {
+					$redirect_to = add_query_arg( 'error', $doaction, $redirect_to );
+				} else {
+					$query_arg = array( 'updated' => 'activated' );
+
+					if ( ! empty( $activated['activated'] ) ) {
+						$query_arg['activated'] = count( $activated['activated'] );
+					}
+
+					if ( ! empty( $activated['errors'] ) ) {
+						$query_arg['notactivated'] = count( $activated['errors'] );
+						set_transient( '_bp_admin_signups_errors', $activated['errors'], 30 );
+					}
+
+					$redirect_to = add_query_arg( $query_arg, $redirect_to );
+				}
+
+				bp_core_redirect( $redirect_to );
+
+			// Handle sign-ups delete
+			} else if ( 'do_delete' == $doaction ) {
+				// nonce check
+				check_admin_referer( 'signups_delete' );
+
+				$deleted = BP_Signup::delete( $signups );
+
+				if ( empty( $deleted ) ) {
+					$redirect_to = add_query_arg( 'error', $doaction, $redirect_to );
+				} else {
+					$query_arg = array( 'updated' => 'deleted' );
+
+					if ( ! empty( $deleted['deleted'] ) ) {
+						$query_arg['deleted'] = count( $deleted['deleted'] );
+					}
+
+					if ( ! empty( $deleted['errors'] ) ) {
+						$query_arg['notdeleted'] = count( $deleted['errors'] );
+						set_transient( '_bp_admin_signups_errors', $deleted['errors'], 30 );
+					}
+
+					$redirect_to = add_query_arg( $query_arg, $redirect_to );
+				}
+
+				bp_core_redirect( $redirect_to );
+
+			// Plugins can update other stuff from here
+			} else {
+				$this->redirect = $redirect_to;
+
+				do_action( 'bp_members_admin_update_signups', $doaction, $_REQUEST, $this->redirect );
+
+				bp_core_redirect( $this->redirect );
+			}
+		}
+	}
+
+	/**
+	 * Display any activation errors.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function signups_display_errors() {
+		// Bail if no activation errors
+		if ( ! $errors = get_transient( '_bp_admin_signups_errors' ) ) {
+			return;
+		}
+
+		foreach ( $errors as $error ) {
+			?>
+			<li><?php echo esc_html( $error[0] );?>: <?php echo esc_html( $error[1] );?></li>
+			<?php
+		}
+
+		// Delete the redirect transient
+		delete_transient( '_bp_admin_signups_errors' );
+	}
+
+	/**
+	 * Signups admin page router.
+	 *
+	 * Depending on the context, display
+	 * - the list of signups
+	 * - or the delete confirmation screen
+	 * - or the activate confirmation screen
+	 * - or the "resend" email confirmation screen
+	 *
+	 * Also prepare the admin notices.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function signups_admin() {
+		$doaction = bp_admin_list_table_current_bulk_action();
+
+		// Prepare notices for admin
+		$notice = array();
+
+		if ( ! empty( $_REQUEST['updated'] ) ) {
+			switch ( $_REQUEST['updated'] ) {
+				case 'resent':
+					$notice = array(
+						'class'   => 'updated',
+						'message' => ''
+					);
+
+					if ( ! empty( $_REQUEST['resent'] ) ) {
+						$notice['message'] .= sprintf(
+							_nx( '%s activation email successfully sent! ', '%s activation emails successfully sent! ',
+							 absint( $_REQUEST['resent'] ),
+							 'signup resent',
+							 'buddypress'
+							),
+							number_format_i18n( absint( $_REQUEST['resent'] ) )
+						);
+					}
+
+					if ( ! empty( $_REQUEST['notsent'] ) ) {
+						$notice['message'] .= sprintf(
+							_nx( '%s activation email was not sent.', '%s activation emails were not sent.',
+							 absint( $_REQUEST['notsent'] ),
+							 'signup notsent',
+							 'buddypress'
+							),
+							number_format_i18n( absint( $_REQUEST['notsent'] ) )
+						);
+
+						if ( empty( $_REQUEST['resent'] ) ) {
+							$notice['class'] = 'error';
+						}
+					}
+
+					break;
+
+				case 'activated':
+					$notice = array(
+						'class'   => 'updated',
+						'message' => ''
+					);
+
+					if ( ! empty( $_REQUEST['activated'] ) ) {
+						$notice['message'] .= sprintf(
+							_nx( '%s account successfully activated! ', '%s accounts successfully activated! ',
+							 absint( $_REQUEST['activated'] ),
+							 'signup resent',
+							 'buddypress'
+							),
+							number_format_i18n( absint( $_REQUEST['activated'] ) )
+						);
+					}
+
+					if ( ! empty( $_REQUEST['notactivated'] ) ) {
+						$notice['message'] .= sprintf(
+							_nx( '%s account was not activated.', '%s accounts were not activated.',
+							 absint( $_REQUEST['notactivated'] ),
+							 'signup notsent',
+							 'buddypress'
+							),
+							number_format_i18n( absint( $_REQUEST['notactivated'] ) )
+						);
+
+						if ( empty( $_REQUEST['activated'] ) ) {
+							$notice['class'] = 'error';
+						}
+					}
+
+					break;
+
+				case 'deleted':
+					$notice = array(
+						'class'   => 'updated',
+						'message' => ''
+					);
+
+					if ( ! empty( $_REQUEST['deleted'] ) ) {
+						$notice['message'] .= sprintf(
+							_nx( '%s sign-up successfully deleted!', '%s sign-ups successfully deleted!',
+							 absint( $_REQUEST['deleted'] ),
+							 'signup deleted',
+							 'buddypress'
+							),
+							number_format_i18n( absint( $_REQUEST['deleted'] ) )
+						);
+					}
+
+					if ( ! empty( $_REQUEST['notdeleted'] ) ) {
+						$notice['message'] .= sprintf(
+							_nx( '%s sign-up was not deleted.', '%s sign-ups were not deleted.',
+							 absint( $_REQUEST['notdeleted'] ),
+							 'signup notdeleted',
+							 'buddypress'
+							),
+							number_format_i18n( absint( $_REQUEST['notdeleted'] ) )
+						);
+
+						if ( empty( $_REQUEST['deleted'] ) ) {
+							$notice['class'] = 'error';
+						}
+					}
+
+					break;
+			}
+		}
+
+		// Process error messages
+		if ( ! empty( $_REQUEST['error'] ) ) {
+			switch ( $_REQUEST['error'] ) {
+				case 'do_resend':
+					$notice = array(
+						'class'   => 'error',
+						'message' => esc_html__( 'There was a problem sending the activation emails, please try again.', 'buddypress' ),
+					);
+					break;
+
+				case 'do_activate':
+					$notice = array(
+						'class'   => 'error',
+						'message' => esc_html__( 'There was a problem activating accounts, please try again.', 'buddypress' ),
+					);
+					break;
+
+				case 'do_delete':
+					$notice = array(
+						'class'   => 'error',
+						'message' => esc_html__( 'There was a problem deleting sign-ups, please try again.', 'buddypress' ),
+					);
+					break;
+			}
+		}
+
+		// Display notices
+		if ( ! empty( $notice ) ) :
+			if ( 'updated' === $notice['class'] ) : ?>
+				<div id="message" class="<?php echo esc_attr( $notice['class'] ); ?>">
+			<?php else: ?>
+				<div class="<?php echo esc_attr( $notice['class'] ); ?>">
+			<?php endif; ?>
+				<p><?php echo $notice['message']; ?></p>
+				<?php if ( ! empty( $_REQUEST['notactivated'] ) || ! empty( $_REQUEST['notdeleted'] ) || ! empty( $_REQUEST['notsent'] ) ) :?>
+					<ul><?php $this->signups_display_errors();?></ul>
+				<?php endif ;?>
+			</div>
+		<?php endif;
+
+		// Show the proper screen
+		switch ( $doaction ) {
+			case 'activate' :
+			case 'delete' :
+			case 'resend' :
+				$this->signups_admin_manage( $doaction );
+				break;
+
+			default:
+				$this->signups_admin_index();
+				break;
+
+		}
+	}
+
+	/**
+	 * This is the list of the Pending accounts (signups).
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @global $plugin_page
+	 * @global $bp_members_signup_list_table
+	 */
+	public function signups_admin_index() {
+		global $plugin_page, $bp_members_signup_list_table;
+
+		$usersearch = ! empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '';
+
+		// Prepare the group items for display
+		$bp_members_signup_list_table->prepare_items();
+
+		$form_url = add_query_arg(
+			array(
+				'page' => 'bp-signups',
+			),
+			bp_get_admin_url( 'users.php' )
+		);
+
+		$search_form_url = remove_query_arg(
+			array(
+				'action',
+				'deleted',
+				'notdeleted',
+				'error',
+				'updated',
+				'delete',
+				'activate',
+				'activated',
+				'notactivated',
+				'resend',
+				'resent',
+				'notresent',
+				'do_delete',
+				'do_activate',
+				'do_resend',
+				'action2',
+				'_wpnonce',
+				'signup_ids'
+			), $_SERVER['REQUEST_URI']
+		);
+
+		?>
+
+		<div class="wrap">
+			<?php screen_icon( 'users' ); ?>
+			<h2>
+				<?php
+				_e( 'Users', 'buddypress' );
+				if ( current_user_can( 'create_users' ) ) { ?>
+					<a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add New', 'user', 'buddypress' ); ?></a>
+				<?php } elseif ( is_multisite() && current_user_can( 'promote_users' ) ) { ?>
+					<a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add Existing', 'user', 'buddypress' ); ?></a>
+				<?php }
+
+				if ( $usersearch ) {
+					printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'buddypress' ) . '</span>', esc_html( $usersearch ) );
+				}
+
+				?>
+			</h2>
+
+			<?php // Display each signups on its own row ?>
+			<?php $bp_members_signup_list_table->views(); ?>
+
+			<form id="bp-signups-search-form" action="<?php echo esc_url( $search_form_url ) ;?>">
+				<input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>" />
+				<?php $bp_members_signup_list_table->search_box( __( 'Search Pending Accounts', 'buddypress' ), 'bp-signups' ); ?>
+			</form>
+
+			<form id="bp-signups-form" action="<?php echo esc_url( $form_url );?>" method="post">
+				<?php $bp_members_signup_list_table->display(); ?>
+			</form>
+		</div>
+	<?php
+	}
+
+	/**
+	 * This is the confirmation screen for actions.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param string $action Delete, activate, or resend activation link.
+	 */
+	public function signups_admin_manage( $action = '' ) {
+		if ( ! is_super_admin() || empty( $action ) ) {
+			die( '-1' );
+		}
+
+		// Get the user IDs from the URL
+		$ids = false;
+		if ( ! empty( $_POST['allsignups'] ) ) {
+			$ids = wp_parse_id_list( $_POST['allsignups'] );
+		} else if ( ! empty( $_GET['signup_id'] ) ) {
+			$ids = absint( $_GET['signup_id'] );
+		}
+
+		if ( empty( $ids ) ) {
+			return false;
+		}
+
+		// Query for signups, and filter out those IDs that don't
+		// correspond to an actual signup
+		$signups_query = BP_Signup::get( array(
+			'include' => $ids,
+		) );
+
+		$signups    = $signups_query['signups'];
+		$signup_ids = wp_list_pluck( $signups, 'signup_id' );
+
+		// Set up strings
+		switch ( $action ) {
+			case 'delete' :
+				$header_text = __( 'Delete Pending Accounts', 'buddypress' );
+				$helper_text = _n( 'You are about to delete the following account:', 'You are about to delete the following accounts:', count( $signup_ids ), 'buddypress' );
+				break;
+
+			case 'activate' :
+				$header_text = __( 'Activate Pending Accounts', 'buddypress' );
+				$helper_text = _n( 'You are about to activate the following account:', 'You are about to activate the following accounts:', count( $signup_ids ), 'buddypress' );
+				break;
+
+			case 'resend' :
+				$header_text = __( 'Resend Activation Emails', 'buddypress' );
+				$helper_text = _n( 'You are about to resend an activation email to the following account:', 'You are about to resend activation emails to the following accounts:', count( $signup_ids ), 'buddypress' );
+				break;
+		}
+
+		// These arguments are added to all URLs
+		$url_args = array( 'page' => 'bp-signups' );
+
+		// These arguments are only added when performing an action
+		$action_args = array(
+			'action'     => 'do_' . $action,
+			'signup_ids' => implode( ',', $signup_ids )
+		);
+
+		$cancel_url = add_query_arg( $url_args, bp_get_admin_url( 'users.php' ) );
+		$action_url = wp_nonce_url(
+			add_query_arg(
+				array_merge( $url_args, $action_args ),
+				bp_get_admin_url( 'users.php' )
+			),
+			'signups_' . $action
+		);
+
+		?>
+
+		<div class="wrap">
+			<?php screen_icon( 'users' ); ?>
+			<h2><?php echo esc_html( $header_text ); ?></h2>
+			<p><?php echo esc_html( $helper_text ); ?></p>
+
+			<ol class="bp-signups-list">
+			<?php foreach ( $signups as $signup ) :
+				$last_notified = mysql2date( 'Y/m/d g:i:s a', $signup->date_sent )
+			?>
+
+				<li>
+					<?php echo esc_html( $signup->user_name ) ?> - <?php echo sanitize_email( $signup->user_email );?>
+
+					<?php if ( 'resend' == $action ) : ?>
+						<p class="description">
+							<?php printf( esc_html__( 'Last notified: %s', 'buddypress'), $last_notified ) ;?>
+
+							<?php if ( ! empty( $signup->recently_sent ) ) : ?>
+								<span class="attention wp-ui-text-notification"> <?php esc_html_e( '(less than 24 hours ago)', 'buddypress' ); ?></span>
+							<?php endif; ?>
+						</p>
+
+					<?php endif; ?>
+				</li>
+
+			<?php endforeach; ?>
+			</ol>
+
+			<?php if ( 'resend' != $action ) : ?>
+				<p><strong><?php esc_html_e( 'This action cannot be undone.', 'buddypress' ) ?></strong></p>
+			<?php endif ; ?>
+
+			<a class="button-primary" href="<?php echo esc_url( $action_url ); ?>"><?php esc_html_e( 'Confirm', 'buddypress' ); ?></a>
+			<a class="button" href="<?php echo esc_url( $cancel_url ); ?>"><?php esc_html_e( 'Cancel', 'buddypress' ) ?></a>
+		</div>
+
+		<?php
+	}
+}
+endif; // class_exists check
+
+// Load the BP Members admin
+add_action( 'bp_init', array( 'BP_Members_Admin', 'register_members_admin' ) );
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-adminbar.php b/wp-content/plugins/buddypress/bp-members/bp-members-adminbar.php
index 5dedf73d66b37841b59436808257e8ae864d4e05..f0897b9b287b73ed03afbb531061b8aaf959c548 100644
--- a/wp-content/plugins/buddypress/bp-members/bp-members-adminbar.php
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-adminbar.php
@@ -50,7 +50,7 @@ function bp_members_admin_bar_my_account_menu() {
 		$wp_admin_bar->add_menu( array(
 			'id'    => 'bp-login',
 			'title' => __( 'Log in', 'buddypress' ),
-			'href'  => wp_login_url()
+			'href'  => wp_login_url( wp_guess_url() )
 		) );
 
 		// Sign up
@@ -92,25 +92,28 @@ function bp_members_admin_bar_user_admin_menu() {
 		'href'  => bp_displayed_user_domain()
 	) );
 
-	// User Admin > Edit this user's profile
-	$wp_admin_bar->add_menu( array(
-		'parent' => $bp->user_admin_menu_id,
-		'id'     => $bp->user_admin_menu_id . '-edit-profile',
-		'title'  => __( "Edit Profile", 'buddypress' ),
-		'href'   => bp_get_members_component_link( 'profile', 'edit' )
-	) );
+	if ( bp_is_active( 'xprofile' ) ) {
+		// User Admin > Edit this user's profile
+		$wp_admin_bar->add_menu( array(
+			'parent' => $bp->user_admin_menu_id,
+			'id'     => $bp->user_admin_menu_id . '-edit-profile',
+			'title'  => __( "Edit Profile", 'buddypress' ),
+			'href'   => bp_get_members_component_link( 'profile', 'edit' )
+		) );
 
-	// User Admin > Edit this user's avatar
-	$wp_admin_bar->add_menu( array(
-		'parent' => $bp->user_admin_menu_id,
-		'id'     => $bp->user_admin_menu_id . '-change-avatar',
-		'title'  => __( "Edit Avatar", 'buddypress' ),
-		'href'   => bp_get_members_component_link( 'profile', 'change-avatar' )
-	) );
+		// User Admin > Edit this user's avatar
+		if ( buddypress()->avatar->show_avatars ) {
+			$wp_admin_bar->add_menu( array(
+				'parent' => $bp->user_admin_menu_id,
+				'id'     => $bp->user_admin_menu_id . '-change-avatar',
+				'title'  => __( "Edit Avatar", 'buddypress' ),
+				'href'   => bp_get_members_component_link( 'profile', 'change-avatar' )
+			) );
+		}
 
+	}
 
 	if ( bp_is_active( 'settings' ) ) {
-
 		// User Admin > Spam/unspam
 		$wp_admin_bar->add_menu( array(
 			'parent' => $bp->user_admin_menu_id,
@@ -139,43 +142,13 @@ add_action( 'admin_bar_menu', 'bp_members_admin_bar_user_admin_menu', 99 );
  * @since BuddyPress (1.5)
  */
 function bp_members_admin_bar_notifications_menu() {
-	global $wp_admin_bar;
 
-	if ( !is_user_logged_in() )
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
 		return false;
-
-	$notifications = bp_core_get_notifications_for_user( bp_loggedin_user_id(), 'object' );
-	$count         = !empty( $notifications ) ? count( $notifications ) : 0;
-	$alert_class   = (int) $count > 0 ? 'pending-count alert' : 'count no-alert';
-	$menu_title    = '<span id="ab-pending-notifications" class="' . $alert_class . '">' . $count . '</span>';
-
-	// Add the top-level Notifications button
-	$wp_admin_bar->add_menu( array(
-		'parent'    => 'top-secondary',
-		'id'        => 'bp-notifications',
-		'title'     => $menu_title,
-		'href'      => bp_loggedin_user_domain(),
-	) );
-
-	if ( !empty( $notifications ) ) {
-		foreach ( (array) $notifications as $notification ) {
-			$wp_admin_bar->add_menu( array(
-				'parent' => 'bp-notifications',
-				'id'     => 'notification-' . $notification->id,
-				'title'  => $notification->content,
-				'href'   => $notification->href
-			) );
-		}
-	} else {
-		$wp_admin_bar->add_menu( array(
-			'parent' => 'bp-notifications',
-			'id'     => 'no-notifications',
-			'title'  => __( 'No new notifications', 'buddypress' ),
-			'href'   => bp_loggedin_user_domain()
-		) );
 	}
 
-	return;
+	bp_notifications_toolbar_menu();
 }
 add_action( 'admin_bar_menu', 'bp_members_admin_bar_notifications_menu', 90 );
 
@@ -189,4 +162,4 @@ function bp_members_remove_edit_page_menu() {
 		remove_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 80 );
 	}
 }
-add_action( 'bp_init', 'bp_members_remove_edit_page_menu', 99 );
+add_action( 'add_admin_bar_menus', 'bp_members_remove_edit_page_menu' );
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-buddybar.php b/wp-content/plugins/buddypress/bp-members/bp-members-buddybar.php
index 613d08775ada1b89db971fca3b47037f09b25889..f3c08c2222e247b3d7efab85318bfd110de70453 100644
--- a/wp-content/plugins/buddypress/bp-members/bp-members-buddybar.php
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-buddybar.php
@@ -17,38 +17,12 @@ if ( !defined( 'ABSPATH' ) ) exit;
  */
 function bp_adminbar_notifications_menu() {
 
-	if ( !is_user_logged_in() )
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
 		return false;
-
-	echo '<li id="bp-adminbar-notifications-menu"><a href="' . bp_loggedin_user_domain() . '">';
-	_e( 'Notifications', 'buddypress' );
-
-	if ( $notifications = bp_core_get_notifications_for_user( bp_loggedin_user_id() ) ) { ?>
-		<span><?php echo count( $notifications ) ?></span>
-	<?php
-	}
-
-	echo '</a>';
-	echo '<ul>';
-
-	if ( $notifications ) {
-		$counter = 0;
-		for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) {
-			$alt = ( 0 == $counter % 2 ) ? ' class="alt"' : ''; ?>
-
-			<li<?php echo $alt ?>><?php echo $notifications[$i] ?></li>
-
-			<?php $counter++;
-		}
-	} else { ?>
-
-		<li><a href="<?php echo bp_loggedin_user_domain() ?>"><?php _e( 'No new notifications.', 'buddypress' ); ?></a></li>
-
-	<?php
 	}
 
-	echo '</ul>';
-	echo '</li>';
+	bp_notifications_buddybar_menu();
 }
 add_action( 'bp_adminbar_menus', 'bp_adminbar_notifications_menu', 8 );
 
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-classes.php b/wp-content/plugins/buddypress/bp-members/bp-members-classes.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2570d5a20ff790d467001b37df83bfe72c38a86
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-classes.php
@@ -0,0 +1,657 @@
+<?php
+
+/**
+ * Signups Management class.
+ *
+ * @package BuddyPress
+ * @subpackage coreClasses
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_Signup {
+
+	/**
+	 * ID of the signup which the object relates to.
+	 *
+	 * @var integer
+	 */
+	public $id;
+
+	/**
+	 * The URL to the full size of the avatar for the user.
+	 *
+	 * @var string
+	 */
+	public $avatar;
+
+	/**
+	 * The username for the user.
+	 *
+	 * @var string
+	 */
+	public $user_login;
+
+	/**
+	 * The email for the user.
+	 *
+	 * @var string
+	 */
+	public $user_email;
+
+	/**
+	 * The full name of the user.
+	 *
+	 * @var string
+	 */
+	public $user_name;
+
+	/**
+	 * Metadata associated with the signup.
+	 *
+	 * @var array
+	 */
+	public $meta;
+
+	/**
+	 * The registered date for the user.
+	 *
+	 * @var string
+	 */
+	public $registered;
+
+	/**
+	 * The activation key for the user.
+	 *
+	 * @var string
+	 */
+	public $activation_key;
+
+
+	/** Public Methods *******************************************************/
+
+	/**
+	 * Class constructor.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param integer $signup_id The ID for the signup being queried.
+	 */
+	public function __construct( $signup_id = 0 ) {
+		if ( !empty( $signup_id ) ) {
+			$this->id = $signup_id;
+			$this->populate();
+		}
+	}
+
+	/**
+	 * Populate the instantiated class with data based on the signup_id provided.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function populate() {
+		global $wpdb;
+
+		$signups_table = buddypress()->members->table_name_signups;
+		$signup        = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$signups_table} WHERE signup_id = %d AND active = 0", $this->id ) );
+
+		$this->avatar         = get_avatar( $signup->user_email, 32 );
+		$this->user_login     = $signup->user_login;
+		$this->user_email     = $signup->user_email;
+		$this->meta           = maybe_unserialize( $signup->meta );
+		$this->user_name      = ! empty( $this->meta['field_1'] ) ? wp_unslash( $this->meta['field_1'] ) : '';
+		$this->registered     = $signup->registered;
+		$this->activation_key = $signup->activation_key;
+	}
+
+	/** Static Methods *******************************************************/
+
+	/**
+	 * Fetch signups based on parameters.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $args the argument to retrieve desired signups
+	 * @return array {
+	 *     @type array $signups Located signups.
+	 *     @type int $total Total number of signups matching params.
+	 * }
+	 */
+	public static function get( $args = array() ) {
+		global $wpdb;
+
+		$r = bp_parse_args( $args,
+			array(
+				'offset'         => 0,
+				'number'         => 1,
+				'usersearch'     => false,
+				'orderby'        => 'signup_id',
+				'order'          => 'DESC',
+				'include'        => false,
+				'activation_key' => '',
+				'user_login'     => '',
+			),
+			'bp_core_signups_get_args'
+		);
+
+		// @todo whitelist sanitization
+		if ( $r['orderby'] !== 'signup_id' ) {
+			$r['orderby'] = 'user_' . $r['orderby'];
+		}
+
+		$r['orderby'] = sanitize_title( $r['orderby'] );
+
+		$sql = array();
+		$signups_table  = buddypress()->members->table_name_signups;
+		$sql['select']  = "SELECT * FROM {$signups_table}";
+		$sql['where']   = array();
+		$sql['where'][] = "active = 0";
+
+		if ( empty( $r['include'] ) ) {
+
+			// Search terms
+			if ( ! empty( $r['usersearch'] ) ) {
+				$search_terms_clean = esc_sql( esc_sql( $r['usersearch'] ) );
+				$search_terms_clean = like_escape( $search_terms_clean );
+				$sql['where'][]     = "( user_login LIKE '%" . $search_terms_clean . "%' OR user_email LIKE '%" . $search_terms_clean . "%' OR meta LIKE '%" . $search_terms_clean . "%' )";
+			}
+
+			// Activation key
+			if ( ! empty( $r['activation_key'] ) ) {
+				$sql['where'][] = $wpdb->prepare( "activation_key = %s", $r['activation_key'] );
+			}
+
+			// User login
+			if ( ! empty( $r['user_login'] ) ) {
+				$sql['where'][] = $wpdb->prepare( "user_login = %s", $r['user_login'] );
+			}
+
+			$sql['orderby'] = "ORDER BY {$r['orderby']}";
+			$sql['order']	= bp_esc_sql_order( $r['order'] );
+			$sql['limit']	= $wpdb->prepare( "LIMIT %d, %d", $r['offset'], $r['number'] );
+		} else {
+			$in = implode( ',', wp_parse_id_list( $r['include'] ) );
+			$sql['in'] = "AND signup_id IN ({$in})";
+		}
+
+		// Implode WHERE clauses
+		$sql['where'] = 'WHERE ' . implode( ' AND ', $sql['where'] );
+
+		$paged_signups = $wpdb->get_results( apply_filters( 'bp_members_signups_paged_query', join( ' ', $sql ), $sql, $args, $r ) );
+
+		if ( empty( $paged_signups ) ) {
+			return array( 'signups' => false, 'total' => false );
+		}
+
+		// Used to calculate a diff between now & last
+		// time an activation link has been resent
+		$now = current_time( 'timestamp', true );
+
+		foreach ( (array) $paged_signups as $key => $signup ) {
+
+			$signup->id   = intval( $signup->signup_id );
+
+			$signup->meta = ! empty( $signup->meta ) ? maybe_unserialize( $signup->meta ) : false;
+
+			$signup->user_name = '';
+			if ( ! empty( $signup->meta['field_1'] ) ) {
+				$signup->user_name = wp_unslash( $signup->meta['field_1'] );
+			}
+
+			// Sent date defaults to date of registration
+			if ( ! empty( $signup->meta['sent_date'] ) ) {
+				$signup->date_sent = $signup->meta['sent_date'];
+			} else {
+				$signup->date_sent = $signup->registered;
+			}
+
+			$sent_at = mysql2date('U', $signup->date_sent );
+			$diff    = $now - $sent_at;
+
+			/**
+			 * add a boolean in case the last time an activation link 
+			 * has been sent happened less than a day ago
+			 */
+			if ( $diff < 1 * DAY_IN_SECONDS ) {
+				$signup->recently_sent = true;
+			}
+
+			if ( ! empty( $signup->meta['count_sent'] ) ) {
+				$signup->count_sent = absint( $signup->meta['count_sent'] );
+			} else {
+				$signup->count_sent = 1;
+			}
+
+			$paged_signups[ $key ] = $signup;
+		}
+
+		unset( $sql['limit'] );
+		$sql['select'] = preg_replace( "/SELECT.*?FROM/", "SELECT COUNT(*) FROM", $sql['select'] );
+		$total_signups = $wpdb->get_var( apply_filters( 'bp_members_signups_count_query', join( ' ', $sql ), $sql, $args, $r ) );
+
+		return array( 'signups' => $paged_signups, 'total' => $total_signups );
+	}
+
+	/**
+	 * Add a signup.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $args
+	 * @return int|bool ID of newly created signup on success, false on
+	 *         failure.
+	 */
+	public static function add( $args = array() ) {
+		global $wpdb;
+
+		$r = bp_parse_args( $args,
+			array(
+				'domain'         => '',
+				'path'           => '',
+				'title'          => '',
+				'user_login'     => '',
+				'user_email'     => '',
+				'registered'     => current_time( 'mysql', true ),
+				'activation_key' => '',
+				'meta'           => '',
+			),
+			'bp_core_signups_add_args'
+		);
+
+		$r['meta'] = maybe_serialize( $r['meta'] );
+
+		$inserted = $wpdb->insert(
+			buddypress()->members->table_name_signups,
+			$r,
+			array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )
+		);
+
+		if ( $inserted ) {
+			$retval = $wpdb->insert_id;
+		} else {
+			$retval = false;
+		}
+
+		return apply_filters( 'bp_core_signups_add', $retval );
+	}
+
+	/**
+	 * Create a WP user at signup.
+	 *
+	 * Since BP 2.0, non-multisite configurations have stored signups in
+	 * the same way as Multisite configs traditionally have: in the
+	 * wp_signups table. However, because some plugins may be looking
+	 * directly in the wp_users table for non-activated signups, we
+	 * mirror signups there by creating "phantom" users, mimicking WP's
+	 * default behavior.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param string $user_login User login string.
+	 * @param string $user_password User password.
+	 * @param string $user_email User email address.
+	 * @param array $usermeta Metadata associated with the signup.
+	 * @return int User id.
+	 */
+	public static function add_backcompat( $user_login = '', $user_password = '', $user_email = '', $usermeta = array() ) {
+		global $wpdb;
+
+		$errors = new WP_Error();
+
+		$user_id = wp_insert_user( array(
+			'user_login'   => $user_login,
+			'user_pass'    => $user_password,
+			'display_name' => sanitize_title( $user_login ),
+			'user_email'   => $user_email
+		) );
+
+		if ( is_wp_error( $user_id ) || empty( $user_id ) ) {
+			$errors->add( 'registerfail', sprintf( __( '<strong>ERROR</strong>: Couldn&#8217;t register you. Please contact the <a href="mailto:%s">webmaster</a>.', 'buddypress' ), bp_get_option( 'admin_email' ) ) );
+			return $errors;
+		}
+
+		// Update the user status to '2', ie "not activated"
+		// (0 = active, 1 = spam, 2 = not active)
+		$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->users} SET user_status = 2 WHERE ID = %d", $user_id ) );
+
+		// WordPress creates these options automatically on
+		// wp_insert_user(), but we delete them so that inactive
+		// signups don't appear in various user counts.
+		delete_user_option( $user_id, 'capabilities' );
+		delete_user_option( $user_id, 'user_level'   );
+
+		// Set any profile data
+		if ( bp_is_active( 'xprofile' ) ) {
+			if ( ! empty( $usermeta['profile_field_ids'] ) ) {
+				$profile_field_ids = explode( ',', $usermeta['profile_field_ids'] );
+
+				foreach ( (array) $profile_field_ids as $field_id ) {
+					if ( empty( $usermeta["field_{$field_id}"] ) ) {
+						continue;
+					}
+
+					$current_field = $usermeta["field_{$field_id}"];
+					xprofile_set_field_data( $field_id, $user_id, $current_field );
+
+					// Save the visibility level
+					$visibility_level = ! empty( $usermeta['field_' . $field_id . '_visibility'] ) ? $usermeta['field_' . $field_id . '_visibility'] : 'public';
+					xprofile_set_field_visibility_level( $field_id, $user_id, $visibility_level );
+				}
+			}
+		}
+
+		return apply_filters( 'bp_core_signups_add_backcompat', $user_id );
+	}
+
+	/**
+	 * Check a user status (from wp_users) on a non-multisite config.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param int $user_id ID of the user being checked.
+	 * @return int|bool The status if found, otherwise false.
+	 */
+	public static function check_user_status( $user_id = 0 ) {
+		global $wpdb;
+
+		if ( empty( $user_id ) ) {
+			return false;
+		}
+
+		$user_status = $wpdb->get_var( $wpdb->prepare( "SELECT user_status FROM {$wpdb->users} WHERE ID = %d", $user_id ) );
+
+		return apply_filters( 'bp_core_signups_check_user_status', intval( $user_status ) );
+	}
+
+	/**
+	 * Activate a signup.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param string $key Activation key.
+	 * @return bool True on success, false on failure.
+	 */
+	public static function validate( $key = '' ) {
+		global $wpdb;
+
+		if ( empty( $key ) ) {
+			return;
+		}
+
+		$activated = $wpdb->update(
+			// Signups table
+			buddypress()->members->table_name_signups,
+			array(
+				'active' => 1,
+				'activated' => current_time( 'mysql', true ),
+			),
+			array(
+				'activation_key' => $key,
+			),
+			// Data sanitization format
+			array(
+				'%d',
+				'%s',
+			),
+			// WHERE sanitization format
+			array(
+				'%s',
+			)
+		);
+
+		return apply_filters( 'bp_core_signups_validate', $activated );
+	}
+
+	/**
+	 * How many inactive signups do we have?
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @return int the number of signups
+	 */
+	public static function count_signups() {
+		global $wpdb;
+
+		$signups_table = buddypress()->members->table_name_signups;
+		$count_signups = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) AS total FROM {$signups_table} WHERE active = %d", 0 ) );
+
+		return apply_filters( 'bp_core_signups_count', (int) $count_signups );
+	}
+
+	/**
+	 * Update the meta for a signup.
+	 *
+	 * This is the way we use to "trace" the last date an activation
+	 * email was sent and how many times activation was sent.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param  array $args
+	 * @return int the signup id
+	 */
+	public static function update( $args = array() ) {
+		global $wpdb;
+
+		$r = bp_parse_args( $args,
+			array(
+				'signup_id'  => 0,
+				'meta'       => array(),
+			),
+			'bp_core_signups_update_args'
+		);
+
+		if ( empty( $r['signup_id'] ) || empty( $r['meta'] ) ) {
+			return false;
+		}
+
+		$wpdb->update(
+			// Signups table
+			buddypress()->members->table_name_signups,
+			// Data to update
+			array(
+				'meta' => serialize( $r['meta'] ),
+			),
+			// WHERE
+			array(
+				'signup_id' => $r['signup_id'],
+			),
+			// Data sanitization format
+			array(
+				'%s',
+			),
+			// WHERE sanitization format
+			array(
+				'%d',
+			)
+		);
+
+		return apply_filters( 'bp_core_signups_update', $r['signup_id'] );
+	}
+
+	/**
+	 * Resend an activation email.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $signup_ids single id or list of ids to resend
+	 * @return array the results
+	 */
+	public static function resend( $signup_ids = array() ) {
+		if ( empty( $signup_ids ) || ! is_array( $signup_ids ) ) {
+			return false;
+		}
+
+		$to_resend = self::get( array(
+			'include' => $signup_ids,
+		) );
+
+		if ( ! $signups = $to_resend['signups'] ) {
+			return false;
+		}
+
+		$result = array();
+
+		do_action( 'bp_core_signup_before_resend', $signup_ids );
+
+		foreach ( $signups as $signup ) {
+
+			$meta               = $signup->meta;
+			$meta['sent_date']  = current_time( 'mysql', true );
+			$meta['count_sent'] = $signup->count_sent + 1;
+
+			// Send activation email
+			if ( is_multisite() ) {
+				wpmu_signup_user_notification( $signup->user_login, $signup->user_email, $signup->activation_key, serialize( $meta ) );
+			} else {
+
+				// Check user status before sending email
+				$user_id = email_exists( $signup->user_email );
+
+				if ( ! empty( $user_id ) && 2 != self::check_user_status( $user_id ) ) {
+
+					// Status is not 2, so user's account has been activated
+					$result['errors'][ $signup->signup_id ] = array( $signup->user_login, esc_html__( 'the sign-up has already been activated.', 'buddypress' ) );
+
+					// repare signups table
+					self::validate( $signup->activation_key );
+
+					continue;
+
+				// Send the validation email
+				} else {
+					bp_core_signup_send_validation_email( false, $signup->user_email, $signup->activation_key );
+				}
+			}
+
+			// Update metas
+			$result['resent'][] = self::update( array(
+				'signup_id' => $signup->signup_id,
+				'meta'      => $meta,
+			) );
+		}
+
+		do_action( 'bp_core_signup_after_resend', $signup_ids, $result );
+
+		return apply_filters( 'bp_core_signup_resend', $result );
+	}
+
+	/**
+	 * Activate a pending account.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $signup_ids Single id or list of ids to resend.
+	 * @return array the results
+	 */
+	public static function activate( $signup_ids = array() ) {
+		if ( empty( $signup_ids ) || ! is_array( $signup_ids ) ) {
+			return false;
+		}
+
+		$to_activate = self::get( array(
+			'include' => $signup_ids,
+		) );
+
+		if ( ! $signups = $to_activate['signups'] ) {
+			return false;
+		}
+
+		$result = array();
+
+		do_action( 'bp_core_signup_before_activate', $signup_ids );
+
+		foreach ( $signups as $signup ) {
+
+			$user = bp_core_activate_signup( $signup->activation_key );
+
+			if ( ! empty( $user->errors ) ) {
+
+				$user_id = username_exists( $signup->user_login ) && 2 != self::check_user_status( $user_id );
+
+				if ( !empty( $user_id ) ) {
+
+					// Status is not 2, so user's account has been activated
+					$result['errors'][ $signup->signup_id ] = array( $signup->user_login, esc_html__( 'the sign-up has already been activated.', 'buddypress' ) );
+
+					// repare signups table
+					self::validate( $signup->activation_key );
+
+				// we have a user id, account is not active, let's delete it
+				} else {
+					$result['errors'][ $signup->signup_id ] = array( $signup->user_login, $user->get_error_message() );
+				}
+
+			} else {
+				$result['activated'][] = $user;
+			}
+		}
+
+		do_action( 'bp_core_signup_after_activate', $signup_ids, $result );
+
+		return apply_filters( 'bp_core_signup_activate', $result );
+	}
+
+	/**
+	 * Delete a pending account.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $signup_ids single id or list of ids to resend
+	 * @return array the results
+	 */
+	public static function delete( $signup_ids = array() ) {
+		global $wpdb;
+
+		if ( empty( $signup_ids ) || ! is_array( $signup_ids ) ) {
+			return false;
+		}
+
+		$to_delete = self::get( array(
+			'include' => $signup_ids,
+		) );
+
+		if ( ! $signups = $to_delete['signups'] ) {
+			return false;
+		}
+
+		$result = array();
+
+		do_action( 'bp_core_signup_before_delete', $signup_ids );
+
+		foreach ( $signups as $signup ) {
+			$user_id = username_exists( $signup->user_login );
+
+			if ( ! empty( $user_id ) && $signup->activation_key == wp_hash( $user_id ) ) {
+
+				if ( 2 != self::check_user_status( $user_id ) ) {
+
+					// Status is not 2, so user's account has been activated
+					$result['errors'][ $signup->signup_id ] = array( $signup->user_login, esc_html__( 'the sign-up has already been activated.', 'buddypress' ) );
+
+					// repare signups table
+					self::validate( $signup->activation_key );
+
+				// we have a user id, account is not active, let's delete it
+				} else {
+					bp_core_delete_account( $user_id );
+				}
+			}
+
+			if ( empty( $result['errors'][ $signup->signup_id ] ) ) {
+				$wpdb->delete(
+					// Signups table
+					buddypress()->members->table_name_signups,
+					// Where
+					array( 'signup_id' => $signup->signup_id, ),
+					// WHERE sanitization format
+					array( '%d', )
+				);
+
+				$result['deleted'][] = $signup->signup_id;
+			}
+		}
+
+		do_action( 'bp_core_signup_after_delete', $signup_ids, $result );
+
+		return apply_filters( 'bp_core_signup_delete', $result );
+	}
+}
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-functions.php b/wp-content/plugins/buddypress/bp-members/bp-members-functions.php
index 4ce8d63cf79254107fe4d4ba78c0ec0ab164d0c5..6dbe403006d5b2b7a690dd9d08c43b5bd9012a31 100644
--- a/wp-content/plugins/buddypress/bp-members/bp-members-functions.php
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-functions.php
@@ -124,24 +124,22 @@ function bp_core_get_users( $args = '' ) {
  */
 function bp_core_get_user_domain( $user_id, $user_nicename = false, $user_login = false ) {
 
-	if ( empty( $user_id ) )
+	if ( empty( $user_id ) ) {
 		return;
+	}
 
-	if ( !$domain = wp_cache_get( 'bp_user_domain_' . $user_id, 'bp' ) ) {
-		$username = bp_core_get_username( $user_id, $user_nicename, $user_login );
+	$username = bp_core_get_username( $user_id, $user_nicename, $user_login );
 
-		if ( bp_is_username_compatibility_mode() )
-			$username = rawurlencode( $username );
+	if ( bp_is_username_compatibility_mode() ) {
+		$username = rawurlencode( $username );
+	}
 
-		$after_domain = bp_core_enable_root_profiles() ? $username : bp_get_members_root_slug() . '/' . $username;
-		$domain       = trailingslashit( bp_get_root_domain() . '/' . $after_domain );
-		$domain       = apply_filters( 'bp_core_get_user_domain_pre_cache', $domain, $user_id, $user_nicename, $user_login );
+	$after_domain = bp_core_enable_root_profiles() ? $username : bp_get_members_root_slug() . '/' . $username;
+	$domain       = trailingslashit( bp_get_root_domain() . '/' . $after_domain );
 
-		// Cache the link
-		if ( !empty( $domain ) ) {
-			wp_cache_set( 'bp_user_domain_' . $user_id, $domain, 'bp' );
-		}
-	}
+	// Don't use this filter.  Subject to removal in a future release.
+	// Use the 'bp_core_get_user_domain' filter instead.
+	$domain       = apply_filters( 'bp_core_get_user_domain_pre_cache', $domain, $user_id, $user_nicename, $user_login );
 
 	return apply_filters( 'bp_core_get_user_domain', $domain, $user_id, $user_nicename, $user_login );
 }
@@ -215,14 +213,15 @@ function bp_core_get_userid_from_nicename( $user_nicename ) {
  *
  * @package BuddyPress Core
  * @param int $uid User ID to check.
- * @global $userdata WordPress user data for the current logged in user.
- * @uses get_userdata() WordPress function to fetch the userdata for a user ID
+ * @uses bp_core_get_core_userdata() Fetch the userdata for a user ID
  * @return string|bool The username of the matched user, or false.
  */
-function bp_core_get_username( $user_id, $user_nicename = false, $user_login = false ) {
-	global $bp;
+function bp_core_get_username( $user_id = 0, $user_nicename = false, $user_login = false ) {
+	$bp = buddypress();
 
-	if ( !$username = wp_cache_get( 'bp_user_username_' . $user_id, 'bp' ) ) {
+	// Check cache for user nicename
+	$username = wp_cache_get( 'bp_user_username_' . $user_id, 'bp' );
+	if ( false === $username ) {
 
 		// Cache not found so prepare to update it
 		$update_cache = true;
@@ -268,14 +267,15 @@ function bp_core_get_username( $user_id, $user_nicename = false, $user_login = f
 		$update_cache = false;
 	}
 
-	// Check $username for empty spaces and default to nicename if found
-	if ( strstr( $username, ' ' ) )
-		$username = bp_members_get_user_nicename( $user_id );
-
 	// Add this to cache
-	if ( ( true == $update_cache ) && !empty( $username ) )
+	if ( ( true === $update_cache ) && !empty( $username ) ) {
 		wp_cache_set( 'bp_user_username_' . $user_id, $username, 'bp' );
 
+	// @todo bust this cache if no $username found?
+	//} else {
+	//	wp_cache_delete( 'bp_user_username_' . $user_id );
+	}
+
 	return apply_filters( 'bp_core_get_username', $username );
 }
 
@@ -389,60 +389,121 @@ function bp_core_get_userlink( $user_id, $no_anchor = false, $just_link = false
 	return apply_filters( 'bp_core_get_userlink', '<a href="' . $url . '" title="' . $display_name . '">' . $display_name . '</a>', $user_id );
 }
 
+/**
+ * Fetch the display name for a group of users.
+ *
+ * Uses the 'Name' field in xprofile if available. Falls back on WP
+ * display_name, and then user_nicename.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $user_ids
+ */
+function bp_core_get_user_displaynames( $user_ids ) {
+
+	// Sanitize
+	$user_ids = wp_parse_id_list( $user_ids );
+
+	// Remove dupes and empties
+	$user_ids = array_unique( array_filter( $user_ids ) );
+
+	if ( empty( $user_ids ) ) {
+		return array();
+	}
+
+	$uncached_ids = array();
+	foreach ( $user_ids as $user_id ) {
+		if ( false === wp_cache_get( 'bp_user_fullname_' . $user_id, 'bp' ) ) {
+			$uncached_ids[] = $user_id;
+		}
+	}
+
+	// Prime caches
+	if ( ! empty( $uncached_ids ) ) {
+		if ( bp_is_active( 'xprofile' ) ) {
+			$fullname_data = BP_XProfile_ProfileData::get_value_byid( 1, $uncached_ids );
+
+			// Key by user_id
+			$fullnames = array();
+			foreach ( $fullname_data as $fd ) {
+				if ( ! empty( $fd->value ) ) {
+					$fullnames[ intval( $fd->user_id ) ] = $fd->value;
+				}
+			}
+
+			// If xprofiledata is not found for any users,  we'll look
+			// them up separately
+			$no_xprofile_ids = array_diff( $uncached_ids, array_keys( $fullnames ) );
+		} else {
+			$fullnames = array();
+			$no_xprofile_ids = $user_ids;
+		}
+
+		if ( ! empty( $no_xprofile_ids ) ) {
+			// Use WP_User_Query because we don't need BP information
+			$query = new WP_User_Query( array(
+				'include'     => $no_xprofile_ids,
+				'fields'      => array( 'ID', 'user_nicename', 'display_name', ),
+				'count_total' => false,
+				'blog_id'     => 0,
+			) );
+
+			foreach ( $query->results as $qr ) {
+				$fullnames[ $qr->ID ] = ! empty( $qr->display_name ) ? $qr->display_name : $qr->user_nicename;
+
+				// If xprofile is active, set this value as the
+				// xprofile display name as well
+				if ( bp_is_active( 'xprofile' ) ) {
+					xprofile_set_field_data( 1, $qr->ID, $fullnames[ $qr->ID ] );
+				}
+			}
+		}
+
+		foreach ( $fullnames as $fuser_id => $fname ) {
+			wp_cache_set( 'bp_user_fullname_' . $fuser_id, $fname, 'bp' );
+		}
+	}
+
+	$retval = array();
+	foreach ( $user_ids as $user_id ) {
+		$retval[ $user_id ] = wp_cache_get( 'bp_user_fullname_' . $user_id, 'bp' );
+	}
+
+	return $retval;
+}
 
 /**
- * Fetch the display name for a user. This will use the "Name" field in xprofile if it is installed.
- * Otherwise, it will fall back to the normal WP display_name, or user_nicename, depending on what has been set.
+ * Fetch the display name for a user.
  *
- * @package BuddyPress Core
- * @global BuddyPress $bp The one true BuddyPress instance
- * @uses wp_cache_get() Will try and fetch the value from the cache, rather than querying the DB again.
- * @uses get_userdata() Fetches the WP userdata for a specific user.
- * @uses xprofile_set_field_data() Will update the field data for a user based on field name and user id.
- * @uses wp_cache_set() Adds a value to the cache.
- * @return string|bool The display name for the user in question, or false if user not found.
+ * @param int|string $user_id_or_username User ID or username.
+ * @return string|bool The display name for the user in question, or false if
+ *         user not found.
  */
 function bp_core_get_user_displayname( $user_id_or_username ) {
 	global $bp;
 
 	$fullname = '';
 
-	if ( !$user_id_or_username )
+	if ( empty( $user_id_or_username ) ) {
 		return false;
+	}
 
-	if ( !is_numeric( $user_id_or_username ) )
+	if ( ! is_numeric( $user_id_or_username ) ) {
 		$user_id = bp_core_get_userid( $user_id_or_username );
-	else
+	} else {
 		$user_id = $user_id_or_username;
+	}
 
-	if ( !$user_id )
+	if ( empty( $user_id ) ) {
 		return false;
+	}
 
-	if ( !$fullname = wp_cache_get( 'bp_user_fullname_' . $user_id, 'bp' ) ) {
-		if ( bp_is_active( 'xprofile' ) ) {
-			$fullname = xprofile_get_field_data( 1, $user_id );
-
-			if ( empty($fullname) ) {
-				$ud = bp_core_get_core_userdata( $user_id );
-
-				if ( !empty( $ud->display_name ) )
-					$fullname = $ud->display_name;
-				elseif ( !empty( $ud->user_nicename ) )
-					$fullname = $ud->user_nicename;
-
-				xprofile_set_field_data( 1, $user_id, $fullname );
-			}
-		} else {
-			$ud = bp_core_get_core_userdata($user_id);
-
-			if ( !empty( $ud->display_name ) )
-				$fullname = $ud->display_name;
-			elseif ( !empty( $ud->user_nicename ) )
-				$fullname = $ud->user_nicename;
-		}
+	$display_names = bp_core_get_user_displaynames( array( $user_id ) );
 
-		if ( !empty( $fullname ) )
-			wp_cache_set( 'bp_user_fullname_' . $user_id, $fullname, 'bp' );
+	if ( ! isset( $display_names[ $user_id ] ) ) {
+		$fullname = false;
+	} else {
+		$fullname = $display_names[ $user_id ];
 	}
 
 	return apply_filters( 'bp_core_get_user_displayname', $fullname, $user_id );
@@ -508,6 +569,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)";
@@ -517,7 +580,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 );
 	}
@@ -526,25 +589,27 @@ function bp_core_get_active_member_count() {
 }
 
 /**
- * Processes a spammed or unspammed user
+ * Process a spammed or unspammed user.
  *
- * This function is called in three ways:
- *  - in bp_settings_action_capabilities() (from the front-end)
- *  - by bp_core_mark_user_spam_admin()    (from wp-admin)
- *  - bp_core_mark_user_ham_admin()        (from wp-admin)
+ * This function is called from three places:
  *
- * @since BuddyPress (1.6)
+ * - in bp_settings_action_capabilities() (from the front-end)
+ * - by bp_core_mark_user_spam_admin()    (from wp-admin)
+ * - bp_core_mark_user_ham_admin()        (from wp-admin)
  *
- * @param int $user_id The user being spammed/hammed
- * @param string $status 'spam' if being marked as spam, 'ham' otherwise
+ * @since BuddyPress (1.6.0)
+ *
+ * @param int $user_id The ID of the user being spammed/hammed.
+ * @param string $status 'spam' if being marked as spam, 'ham' otherwise.
+ * @param bool $do_wp_cleanup True to force the cleanup of WordPress content
+ *        and status, otherwise false. Generally, this should only be false if
+ *        WordPress is expected to have performed this cleanup independently,
+ *        as when hooked to 'make_spam_user'.
+ * @return bool True on success, false on failure.
  */
-function bp_core_process_spammer_status( $user_id, $status ) {
+function bp_core_process_spammer_status( $user_id, $status, $do_wp_cleanup = true ) {
 	global $wpdb;
 
-	// Only super admins can currently spam users
-	if ( !is_super_admin() || bp_is_my_profile() )
-		return;
-
 	// Bail if no user ID
 	if ( empty( $user_id ) )
 		return;
@@ -564,8 +629,14 @@ function bp_core_process_spammer_status( $user_id, $status ) {
 	remove_action( 'make_spam_user', 'bp_core_mark_user_spam_admin' );
 	remove_action( 'make_ham_user',  'bp_core_mark_user_ham_admin'  );
 
+	// Determine if we are on an admin page
+	$is_admin = is_admin();
+	if ( $is_admin && ! defined( 'DOING_AJAX' ) ) {
+		$is_admin = (bool) ( buddypress()->members->admin->user_page !== get_current_screen()->id );
+	}
+
 	// When marking as spam in the Dashboard, these actions are handled by WordPress
-	if ( !is_admin() ) {
+	if ( $do_wp_cleanup ) {
 
 		// Get the blogs for the user
 		$blogs = get_blogs_of_user( $user_id, true );
@@ -608,6 +679,10 @@ function bp_core_process_spammer_status( $user_id, $status ) {
 	// Allow plugins to do neat things
 	do_action( 'bp_core_process_spammer_status', $user_id, $is_spam );
 
+	// Put things back how we found them
+	add_action( 'make_spam_user', 'bp_core_mark_user_spam_admin' );
+	add_action( 'make_ham_user',  'bp_core_mark_user_ham_admin'  );
+
 	return true;
 }
 
@@ -619,7 +694,7 @@ function bp_core_process_spammer_status( $user_id, $status ) {
  * @param int $user_id The user id passed from the make_spam_user hook
  */
 function bp_core_mark_user_spam_admin( $user_id ) {
-	bp_core_process_spammer_status( $user_id, 'spam' );
+	bp_core_process_spammer_status( $user_id, 'spam', false );
 }
 add_action( 'make_spam_user', 'bp_core_mark_user_spam_admin' );
 
@@ -631,7 +706,7 @@ add_action( 'make_spam_user', 'bp_core_mark_user_spam_admin' );
  * @param int $user_id The user id passed from the make_ham_user hook
  */
 function bp_core_mark_user_ham_admin( $user_id ) {
-	bp_core_process_spammer_status( $user_id, 'ham' );
+	bp_core_process_spammer_status( $user_id, 'ham', false );
 }
 add_action( 'make_ham_user', 'bp_core_mark_user_ham_admin' );
 
@@ -807,6 +882,149 @@ function bp_is_user_inactive( $user_id = 0 ) {
 	return !bp_is_user_active( $user_id );
 }
 
+/**
+ * Update a user's last activity.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @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
+	if ( empty( $user_id ) ) {
+		$user_id = bp_loggedin_user_id();
+	}
+
+	// Bail if the user id is 0, as there's nothing to update
+	if ( empty( $user_id ) ) {
+		return false;
+	}
+
+	// Fall back on current time
+	if ( empty( $time ) ) {
+		$time = bp_core_current_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 );
+	remove_filter( 'get_user_metadata', '_bp_get_user_meta_last_activity_warning', 10, 3 );
+	update_user_meta( $user_id, 'last_activity', $time );
+	add_filter( 'update_user_metadata', '_bp_update_user_meta_last_activity_warning', 10, 4 );
+	add_filter( 'get_user_metadata', '_bp_get_user_meta_last_activity_warning', 10, 3 );
+
+	return BP_Core_User::update_last_activity( $user_id, $time );
+}
+
+/**
+ * Backward compatibility for 'last_activity' usermeta fetching.
+ *
+ * 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.
+ */
+function bp_get_user_last_activity( $user_id = 0 ) {
+	$activity = '';
+
+	$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 );
+}
+
+/**
+ * Migrate last_activity data from the usermeta table to the activity table.
+ *
+ * Generally, this function is only run when BP is upgraded to 2.0. It can also
+ * be called directly from the BuddyPress Tools panel.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_last_activity_migrate() {
+	global $wpdb;
+
+	$bp = buddypress();
+
+	// The "NOT IN" clause prevents duplicates
+	$sql = "INSERT INTO {$bp->members->table_name_last_activity} (`user_id`, `component`, `type`, `action`, `content`, `primary_link`, `item_id`, `date_recorded` ) (
+		  SELECT user_id, '{$bp->members->id}' as component, 'last_activity' as type, '' as action, '' as content, '' as primary_link, 0 as item_id, 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'
+		    )
+	);";
+
+	return $wpdb->query( $sql );
+}
+
 /**
  * Fetch every post that is authored by the given user for the current blog.
  *
@@ -878,6 +1096,23 @@ function bp_core_delete_account( $user_id = 0 ) {
 	return $retval;
 }
 
+/**
+ * Delete a user's avatar when the user is deleted.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user who is about to be deleted.
+ * @return bool True on success, false on failure.
+ */
+function bp_core_delete_avatar_on_user_delete( $user_id ) {
+	return bp_core_delete_existing_avatar( array(
+		'item_id' => $user_id,
+		'object'  => 'user',
+	) );
+}
+add_action( 'wpmu_delete_user', 'bp_core_delete_avatar_on_user_delete' );
+add_action( 'delete_user', 'bp_core_delete_avatar_on_user_delete' );
+
 /**
  * Localization safe ucfirst() support.
  *
@@ -892,21 +1127,6 @@ function bp_core_ucfirst( $str ) {
 	}
 }
 
-/**
- * Strips spaces from usernames that are created using add_user() and wp_insert_user()
- *
- * @package BuddyPress Core
- */
-function bp_core_strip_username_spaces( $username ) {
-	// Don't alter the user_login of existing users, as it causes user_nicename problems.
-	// See http://trac.buddypress.org/ticket/2642
-	if ( username_exists( $username ) && ( !bp_is_username_compatibility_mode() ) )
-		return $username;
-
-	return str_replace( ' ', '-', $username );
-}
-add_action( 'pre_user_login', 'bp_core_strip_username_spaces' );
-
 /**
  * When a user logs in, check if they have been marked as a spammer. If yes then simply
  * redirect them to the home page and stop them from logging in.
@@ -940,8 +1160,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();
@@ -954,6 +1174,10 @@ function bp_core_can_edit_settings() {
 	if ( bp_is_my_profile() )
 		return true;
 
+	if ( is_super_admin( bp_displayed_user_id() ) && ! is_super_admin() ) {
+		return false;
+	}
+
 	if ( bp_current_user_can( 'bp_moderate' ) || current_user_can( 'edit_users' ) )
 		return true;
 
@@ -981,12 +1205,15 @@ function bp_core_flush_illegal_names() {
 function bp_core_get_illegal_names( $value = '', $oldvalue = '' ) {
 
 	// Make sure $value is array
-	if ( empty( $value ) )
+	if ( empty( $value ) ) {
 		$db_illegal_names = array();
-	if ( is_array( $value ) )
+	}
+
+	if ( is_array( $value ) ) {
 		$db_illegal_names = $value;
-	elseif ( is_string( $value ) )
+	} elseif ( is_string( $value ) ) {
 		$db_illegal_names = explode( ' ', $value );
+	}
 
 	// Add the core components' slugs to the banned list even if their components aren't active.
 	$bp_component_slugs = array(
@@ -999,6 +1226,7 @@ function bp_core_get_illegal_names( $value = '', $oldvalue = '' ) {
 		'friends',
 		'search',
 		'settings',
+		'notifications',
 		'register',
 		'activate'
 	);
@@ -1014,12 +1242,15 @@ function bp_core_get_illegal_names( $value = '', $oldvalue = '' ) {
 		'BP_FRIENDS_SLUG',
 		'BP_SEARCH_SLUG',
 		'BP_SETTINGS_SLUG',
+		'BP_NOTIFICATIONS_SLUG',
 		'BP_REGISTER_SLUG',
 		'BP_ACTIVATION_SLUG',
 	);
-	foreach( $slug_constants as $constant )
-		if ( defined( $constant ) )
+	foreach( $slug_constants as $constant ) {
+		if ( defined( $constant ) ) {
 			$bp_component_slugs[] = constant( $constant );
+		}
+	}
 
 	// Add our slugs to the array and allow them to be filtered
 	$filtered_illegal_names = apply_filters( 'bp_core_illegal_usernames', array_merge( array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' ), $bp_component_slugs ) );
@@ -1119,52 +1350,83 @@ function bp_core_add_validation_error_messages( WP_Error $errors, $validation_re
  */
 function bp_core_validate_user_signup( $user_name, $user_email ) {
 
-	$errors = new WP_Error();
+	// Make sure illegal names include BuddyPress slugs and values
+	bp_core_flush_illegal_names();
 
-	// Apply any user_login filters added by BP or other plugins before validating
-	$user_name = apply_filters( 'pre_user_login', $user_name );
+	// WordPress Multisite has its own validation. Use it, so that we
+	// properly mirror restrictions on username, etc.
+	if ( function_exists( 'wpmu_validate_user_signup' ) ) {
+		$result = wpmu_validate_user_signup( $user_name, $user_email );
 
-	if ( empty( $user_name ) )
-		$errors->add( 'user_name', __( 'Please enter a username', 'buddypress' ) );
+	// When not running Multisite, we perform our own validation. What
+	// follows reproduces much of the logic of wpmu_validate_user_signup(),
+	// minus the multisite-specific restrictions on user_login
+	} else {
+		$errors = new WP_Error();
 
-	// Make sure illegal names include BuddyPress slugs and values
-	bp_core_flush_illegal_names();
+		// Apply any user_login filters added by BP or other plugins before validating
+		$user_name = apply_filters( 'pre_user_login', $user_name );
 
-	$illegal_names = get_site_option( 'illegal_names' );
+		// User name can't be empty
+		if ( empty( $user_name ) ) {
+			$errors->add( 'user_name', __( 'Please enter a username', 'buddypress' ) );
+		}
+
+		// user name can't be on the blacklist
+		$illegal_names = get_site_option( 'illegal_names' );
+		if ( in_array( $user_name, (array) $illegal_names ) ) {
+			$errors->add( 'user_name', __( 'That username is not allowed', 'buddypress' ) );
+		}
 
-	if ( in_array( $user_name, (array) $illegal_names ) )
-		$errors->add( 'user_name', __( 'That username is not allowed', 'buddypress' ) );
+		// User name must pass WP's validity check
+		if ( ! validate_username( $user_name ) ) {
+			$errors->add( 'user_name', __( 'Usernames can contain only letters, numbers, ., -, and @', 'buddypress' ) );
+		}
 
-	if ( ! validate_username( $user_name ) )
-		$errors->add( 'user_name', __( 'Usernames can contain only letters, numbers, ., -, *, and @', 'buddypress' ) );
+		// Minimum of 4 characters
+		if ( strlen( $user_name ) < 4 ) {
+			$errors->add( 'user_name',  __( 'Username must be at least 4 characters', 'buddypress' ) );
+		}
 
-	if( strlen( $user_name ) < 4 )
-		$errors->add( 'user_name',  __( 'Username must be at least 4 characters', 'buddypress' ) );
+		// No underscores. @todo Why not?
+		if ( false !== strpos( ' ' . $user_name, '_' ) ) {
+			$errors->add( 'user_name', __( 'Sorry, usernames may not contain the character "_"!', 'buddypress' ) );
+		}
 
-	if ( strpos( ' ' . $user_name, '_' ) != false )
-		$errors->add( 'user_name', __( 'Sorry, usernames may not contain the character "_"!', 'buddypress' ) );
+		// No usernames that are all numeric. @todo Why?
+		$match = array();
+		preg_match( '/[0-9]*/', $user_name, $match );
+		if ( $match[0] == $user_name ) {
+			$errors->add( 'user_name', __( 'Sorry, usernames must have letters too!', 'buddypress' ) );
+		}
 
-	// Is the user_name all numeric?
-	$match = array();
-	preg_match( '/[0-9]*/', $user_name, $match );
+		// Check into signups
+		$signups = BP_Signup::get( array(
+			'user_login' => $user_name,
+		) );
 
-	if ( $match[0] == $user_name )
-		$errors->add( 'user_name', __( 'Sorry, usernames must have letters too!', 'buddypress' ) );
+		$signup = isset( $signups['signups'] ) && ! empty( $signups['signups'][0] ) ? $signups['signups'][0] : false;
 
-	// Check if the username has been used already.
-	if ( username_exists( $user_name ) )
-		$errors->add( 'user_name', __( 'Sorry, that username already exists!', 'buddypress' ) );
+		// Check if the username has been used already.
+		if ( username_exists( $user_name ) || ! empty( $signup ) ) {
+			$errors->add( 'user_name', __( 'Sorry, that username already exists!', 'buddypress' ) );
+		}
 
-	// Validate the email address and process the validation results into
-	// error messages
-	$validate_email = bp_core_validate_email_address( $user_email );
-	bp_core_add_validation_error_messages( $errors, $validate_email );
+		// Validate the email address and process the validation results into
+		// error messages
+		$validate_email = bp_core_validate_email_address( $user_email );
+		bp_core_add_validation_error_messages( $errors, $validate_email );
 
-	// Assemble the return array
-	$result = array( 'user_name' => $user_name, 'user_email' => $user_email, 'errors' => $errors );
+		// Assemble the return array
+		$result = array(
+			'user_name'  => $user_name,
+			'user_email' => $user_email,
+			'errors'     => $errors,
+		);
 
-	// Apply WPMU legacy filter
-	$result = apply_filters( 'wpmu_validate_user_signup', $result );
+		// Apply WPMU legacy filter
+		$result = apply_filters( 'wpmu_validate_user_signup', $result );
+	}
 
  	return apply_filters( 'bp_core_validate_user_signup', $result );
 }
@@ -1177,74 +1439,61 @@ function bp_core_validate_blog_signup( $blog_url, $blog_title ) {
 }
 
 function bp_core_signup_user( $user_login, $user_password, $user_email, $usermeta ) {
-	global $bp, $wpdb;
+	global $bp;
+
+	// We need to cast $user_id to pass to the filters
+	$user_id = false;
 
 	// Multisite installs have their own install procedure
 	if ( is_multisite() ) {
 		wpmu_signup_user( $user_login, $user_email, $usermeta );
 
-		// On multisite, the user id is not created until the user activates the account
-		// but we need to cast $user_id to pass to the filters
-		$user_id = false;
-
 	} else {
-		$errors = new WP_Error();
-
-		$user_id = wp_insert_user( array(
-			'user_login' => $user_login,
-			'user_pass' => $user_password,
-			'display_name' => sanitize_title( $user_login ),
-			'user_email' => $user_email
-		) );
+		// Format data
+		$user_login     = preg_replace( '/\s+/', '', sanitize_user( $user_login, true ) );
+		$user_email     = sanitize_email( $user_email );
+		$activation_key = substr( md5( time() . rand() . $user_email ), 0, 16 );
+
+		/**
+		 * WordPress's default behavior is to create user accounts
+		 * immediately at registration time. BuddyPress uses a system
+		 * borrowed from WordPress Multisite, where signups are stored
+		 * separately and accounts are only created at the time of
+		 * activation. For backward compatibility with plugins that may
+		 * be anticipating WP's default behavior, BP silently creates
+		 * accounts for registrations (though it does not use them). If
+		 * you know that you are not running any plugins dependent on
+		 * these pending accounts, you may want to save a little DB
+		 * clutter by defining setting the BP_SIGNUPS_SKIP_USER_CREATION
+		 * to true in your wp-config.php file.
+		 */
+		if ( ! defined( 'BP_SIGNUPS_SKIP_USER_CREATION' ) || ! BP_SIGNUPS_SKIP_USER_CREATION ) {
+			$user_id = BP_Signup::add_backcompat( $user_login, $user_password, $user_email, $usermeta );
+
+			if ( is_wp_error( $user_id ) ) {
+				return $user_id;
+			}
 
-		if ( is_wp_error( $user_id ) || empty( $user_id ) ) {
-			$errors->add( 'registerfail', sprintf( __('<strong>ERROR</strong>: Couldn&#8217;t register you... please contact the <a href="mailto:%s">webmaster</a> !', 'buddypress' ), bp_get_option( 'admin_email' ) ) );
-			return $errors;
+			$activation_key = wp_hash( $user_id );
+			update_user_meta( $user_id, 'activation_key', $activation_key );
 		}
 
-		// Update the user status to '2' which we will use as 'not activated' (0 = active, 1 = spam, 2 = not active)
-		$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->users} SET user_status = 2 WHERE ID = %d", $user_id ) );
-
-		// Set any profile data
-		if ( bp_is_active( 'xprofile' ) ) {
-			if ( !empty( $usermeta['profile_field_ids'] ) ) {
-				$profile_field_ids = explode( ',', $usermeta['profile_field_ids'] );
-
-				foreach( (array) $profile_field_ids as $field_id ) {
-					if ( empty( $usermeta["field_{$field_id}"] ) )
-						continue;
+		$args = array(
+			'user_login'     => $user_login,
+			'user_email'     => $user_email,
+			'activation_key' => $activation_key,
+			'meta'           => $usermeta,
+		);
 
-					$current_field = $usermeta["field_{$field_id}"];
-					xprofile_set_field_data( $field_id, $user_id, $current_field );
+		BP_Signup::add( $args );
 
-					// Save the visibility level
-					$visibility_level = !empty( $usermeta['field_' . $field_id . '_visibility'] ) ? $usermeta['field_' . $field_id . '_visibility'] : 'public';
-					xprofile_set_field_visibility_level( $field_id, $user_id, $visibility_level );
-				}
-			}
-		}
-	}
-	$bp->signup->username = $user_login;
-
-	/***
-	 * Now generate an activation key and send an email to the user so they can activate their
-	 * account and validate their email address. Multisite installs send their own email, so
-	 * this is only for single blog installs.
-	 *
-	 * To disable sending activation emails you can user the filter
-	 * 'bp_core_signup_send_activation_key' and return false. Note that this will only disable
-	 * the email - a key will still be generated, and the account must still be activated
-	 * before use.
-	 */
-	if ( !is_multisite() ) {
-		$activation_key = wp_hash( $user_id );
-		update_user_meta( $user_id, 'activation_key', $activation_key );
-
-		if ( apply_filters( 'bp_core_signup_send_activation_key', true ) ) {
+		if ( apply_filters( 'bp_core_signup_send_activation_key', true, $user_id, $user_email, $activation_key, $usermeta ) ) {
 			bp_core_signup_send_validation_email( $user_id, $user_email, $activation_key );
 		}
 	}
 
+	$bp->signup->username = $user_login;
+
 	do_action( 'bp_core_signup_user', $user_id, $user_login, $user_password, $user_email, $usermeta );
 
 	return $user_id;
@@ -1267,54 +1516,121 @@ function bp_core_activate_signup( $key ) {
 		$user = wpmu_activate_signup( $key );
 
 		// If there were errors, add a message and redirect
-		if ( !empty( $user->errors ) ) {
+		if ( ! empty( $user->errors ) ) {
 			return $user;
 		}
 
 		$user_id = $user['user_id'];
 
-		// Set any profile data
-		if ( bp_is_active( 'xprofile' ) ) {
-			if ( !empty( $user['meta']['profile_field_ids'] ) ) {
-				$profile_field_ids = explode( ',', $user['meta']['profile_field_ids'] );
+	} else {
+		$signups = BP_Signup::get( array(
+			'activation_key' => $key,
+		) );
 
-				foreach( (array) $profile_field_ids as $field_id ) {
-					$current_field = isset( $user['meta']["field_{$field_id}"] ) ? $user['meta']["field_{$field_id}"] : false;
+		if ( empty( $signups['signups'] ) ) {
+			return new WP_Error( 'invalid_key', __( 'Invalid activation key.', 'buddypress' ) );
+		}
 
-					if ( !empty( $current_field ) )
-						xprofile_set_field_data( $field_id, $user_id, $current_field );
+		$signup = $signups['signups'][0];
 
-					// Save the visibility level
-					$visibility_level = !empty( $user['meta']['field_' . $field_id . '_visibility'] ) ? $user['meta']['field_' . $field_id . '_visibility'] : 'public';
-					xprofile_set_field_visibility_level( $field_id, $user_id, $visibility_level );
-				}
+		if ( $signup->active ) {
+			if ( empty( $signup->domain ) ) {
+				return new WP_Error( 'already_active', __( 'The user is already active.', 'buddypress' ), $signup );
+			} else {
+				return new WP_Error( 'already_active', __( 'The site is already active.', 'buddypress' ), $signup );
 			}
 		}
-	} else {
 
-		// Get the user_id based on the $key
-		$user_id = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = 'activation_key' AND meta_value = %s", $key ) );
+		// password is hashed again in wp_insert_user
+		$password = wp_generate_password( 12, false );
+
+		$user_id = username_exists( $signup->user_login );
+
+		// Create the user
+		if ( ! $user_id ) {
+			$user_id = wp_create_user( $signup->user_login, $password, $signup->user_email );
 
-		if ( empty( $user_id ) )
-			return new WP_Error( 'invalid_key', __( 'Invalid activation key', 'buddypress' ) );
+		// If a user ID is found, this may be a legacy signup, or one
+		// created locally for backward compatibility. Process it.
+		} else if ( $key == wp_hash( $user_id ) ) {
+			// Change the user's status so they become active
+			if ( ! $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->users} SET user_status = 0 WHERE ID = %d", $user_id ) ) ) {
+				return new WP_Error( 'invalid_key', __( 'Invalid activation key', 'buddypress' ) );
+			}
+
+			bp_delete_user_meta( $user_id, 'activation_key' );
 
-		// Change the user's status so they become active
-		if ( !$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->users} SET user_status = 0 WHERE ID = %d", $user_id ) ) )
-			return new WP_Error( 'invalid_key', __( 'Invalid activation key', 'buddypress' ) );
+			$member = get_userdata( $user_id );
+			$member->set_role( get_option('default_role') );
+
+			$user_already_created = true;
+
+		} else {
+			$user_already_exists = true;
+		}
+
+		if ( ! $user_id ) {
+			return new WP_Error( 'create_user', __( 'Could not create user', 'buddypress' ), $signup );
+		}
+
+		// Fetch the signup so we have the data later on
+		$signups = BP_Signup::get( array(
+			'activation_key' => $key,
+		) );
+
+		$signup = isset( $signups['signups'] ) && ! empty( $signups['signups'][0] ) ? $signups['signups'][0] : false;
+
+		// Activate the signup
+		BP_Signup::validate( $key );
+
+		if ( isset( $user_already_exists ) ) {
+			return new WP_Error( 'user_already_exists', __( 'That username is already activated.', 'buddypress' ), $signup );
+		}
+
+		// Set up data to pass to the legacy filter
+		$user = array(
+			'user_id'  => $user_id,
+			'password' => $signup->meta['password'],
+			'meta'     => $signup->meta,
+		);
 
 		// Notify the site admin of a new user registration
 		wp_new_user_notification( $user_id );
 
-		// Remove the activation key meta
-		delete_user_meta( $user_id, 'activation_key' );
+		if ( isset( $user_already_created ) ) {
+			do_action( 'bp_core_activated_user', $user_id, $key, $user );
+			return $user_id;
+		}
+	}
+
+	// Set any profile data
+	if ( bp_is_active( 'xprofile' ) ) {
+		if ( ! empty( $user['meta']['profile_field_ids'] ) ) {
+			$profile_field_ids = explode( ',', $user['meta']['profile_field_ids'] );
+
+			foreach( (array) $profile_field_ids as $field_id ) {
+				$current_field = isset( $user['meta']["field_{$field_id}"] ) ? $user['meta']["field_{$field_id}"] : false;
+
+				if ( !empty( $current_field ) )
+					xprofile_set_field_data( $field_id, $user_id, $current_field );
+
+				// Save the visibility level
+				$visibility_level = ! empty( $user['meta']['field_' . $field_id . '_visibility'] ) ? $user['meta']['field_' . $field_id . '_visibility'] : 'public';
+				xprofile_set_field_visibility_level( $field_id, $user_id, $visibility_level );
+			}
+		}
 	}
 
 	// Update the display_name
-	wp_update_user( array( 'ID' => $user_id, 'display_name' => bp_core_get_user_displayname( $user_id ) ) );
+	wp_update_user( array(
+		'ID'           => $user_id,
+		'display_name' => bp_core_get_user_displayname( $user_id ),
+	) );
 
 	// Set the password on multisite installs
-	if ( is_multisite() && !empty( $user['meta']['password'] ) )
+	if ( ! empty( $user['meta']['password'] ) ) {
 		$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->users} SET user_pass = %s WHERE ID = %d", $user['meta']['password'], $user_id ) );
+	}
 
 	do_action( 'bp_core_activated_user', $user_id, $key, $user );
 
@@ -1337,7 +1653,6 @@ function bp_core_new_user_activity( $user ) {
 
 	bp_activity_add( array(
 		'user_id'   => $user_id,
-		'action'    => apply_filters( 'bp_core_activity_registered_member_action', sprintf( __( '%s became a registered member', 'buddypress' ), $userlink ), $user_id ),
 		'component' => 'xprofile',
 		'type'      => 'new_member'
 	) );
@@ -1401,32 +1716,98 @@ function bp_core_signup_send_validation_email( $user_id, $user_email, $key ) {
 }
 
 /**
- * Stop user accounts logging in that have not been activated yet (user_status = 2).
- *
- * Note: This is only applicable for single site WordPress installs.
- * Multisite has their own DB table - 'wp_signups' - dedicated for unactivated users.
- * See {@link wpmu_signup_user()} and {@link wpmu_validate_user_signup()}.
+ * Display a "resend email" link when an unregistered user attempts to log in.
  *
- * @param WP_User|WP_Error $user Either the WP_User object or the WP_Error object
- * @return WP_User|WP_Error If the user is not a spammer, return the WP_User object. Otherwise a new WP_Error object.
+ * @param WP_User|WP_Error $user Either the WP_User or the WP_Error object
+ * @param string $username The inputted, attempted username.
+ * @param string $password The inputted, attempted password.
+ * @return WP_User|WP_Error
  *
  * @since BuddyPress (1.2.2)
  */
-function bp_core_signup_disable_inactive( $user ) {
-	// check to see if the $user has already failed logging in, if so return $user as-is
-	if ( is_wp_error( $user ) || empty( $user ) )
+function bp_core_signup_disable_inactive( $user = null, $username = '', $password ='' ) {
+	// login form not used
+	if ( empty( $username ) && empty( $password ) ) {
 		return $user;
+	}
 
-	// the user exists; now do a check to see if the user has activated their account or not
-	// NOTE: this is only applicable for single site WordPress installs!
-	// if unactivated, stop the login now!
-	if ( is_a( $user, 'WP_User' ) && 2 == $user->user_status )
-		return new WP_Error( 'bp_account_not_activated', __( '<strong>ERROR</strong>: Your account has not been activated. Check your email for the activation link.', 'buddypress' ) );
+	// An existing WP_User with a user_status of 2 is either a legacy
+	// signup, or is a user created for backward compatibility. See
+	// {@link bp_core_signup_user()} for more details.
+	if ( is_a( $user, 'WP_User' ) && 2 == $user->user_status ) {
+		$user_login = $user->user_login;
 
-	// user has activated their account! all clear!
-	return $user;
+	// If no WP_User is found corresponding to the username, this
+	// is a potential signup
+	} elseif ( is_wp_error( $user ) && 'invalid_username' == $user->get_error_code() ) {
+		$user_login = $username;
+
+	// This is an activated user, so bail
+	} else {
+		return $user;
+	}
+
+	// Look for the unactivated signup corresponding to the login name
+	$signup = BP_Signup::get( array( 'user_login' => sanitize_user( $user_login ) ) );
+
+	// No signup or more than one, something is wrong. Let's bail.
+	if ( empty( $signup['signups'][0] ) || $signup['total'] > 1 ) {
+		return $user;
+	}
+
+	// Unactivated user account found!
+	// Set up the feedback message
+	$signup_id = $signup['signups'][0]->signup_id;
+
+	$resend_url_params = array(
+		'action' => 'bp-resend-activation',
+		'id'     => $signup_id,
+	);
+
+	$resend_url = wp_nonce_url(
+		add_query_arg( $resend_url_params, wp_login_url() ),
+		'bp-resend-activation'
+	);
+
+	$resend_string = '<br /><br />' . sprintf( __( 'If you have not received an email yet, <a href="%s">click here to resend it</a>.', 'buddypress' ), $resend_url );
+
+	return new WP_Error( 'bp_account_not_activated', __( '<strong>ERROR</strong>: Your account has not been activated. Check your email for the activation link.', 'buddypress' ) . $resend_string );
+}
+add_filter( 'authenticate', 'bp_core_signup_disable_inactive', 30, 3 );
+
+/**
+ * On the login screen, resends the activation email for a user.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @see bp_core_signup_disable_inactive()
+ */
+function bp_members_login_resend_activation_email() {
+	global $error;
+
+	if ( empty( $_GET['id'] ) || empty( $_GET['_wpnonce'] ) ) {
+		return;
+	}
+
+	// verify nonce
+	if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'bp-resend-activation' ) ) {
+		die( 'Security check' );
+	}
+
+	$signup_id = (int) $_GET['id'];
+
+	// resend the activation email
+	// also updates the 'last sent' and '# of emails sent' values
+	$resend = BP_Signup::resend( array( $signup_id ) );
+
+	// add feedback message
+	if ( ! empty( $resend['errors'] ) ) {
+		$error = __( '<strong>ERROR</strong>: Your account has already been activated.', 'buddypress' );
+	} else {
+		$error = __( 'Activation email resent!  Please check your inbox or spam folder.', 'buddypress' );
+	}
 }
-add_filter( 'authenticate', 'bp_core_signup_disable_inactive', 30 );
+add_action( 'login_form_bp-resend-activation', 'bp_members_login_resend_activation_email' );
 
 /**
  * Kill the wp-signup.php if custom registration signup templates are present
@@ -1470,7 +1851,14 @@ add_action( 'bp_init', 'bp_core_wpsignup_redirect' );
  */
 function bp_stop_live_spammer() {
 	// if we're on the login page, stop now to prevent redirect loop
-	if ( strpos( $GLOBALS['pagenow'], 'wp-login.php' ) !== false ) {
+	$is_login = false;
+	if ( isset( $_GLOBALS['pagenow'] ) && false !== strpos( $GLOBALS['pagenow'], 'wp-login.php' ) ) {
+		$is_login = true;
+	} else if ( isset( $_SERVER['SCRIPT_NAME'] ) && false !== strpos( $_SERVER['SCRIPT_NAME'], 'wp-login.php' ) ) {
+		$is_login = true;
+	}
+
+	if ( $is_login ) {
 		return;
 	}
 
@@ -1513,4 +1901,4 @@ function bp_live_spammer_login_error() {
 	// shake shake shake!
 	add_action( 'login_head', 'wp_shake_js', 12 );
 }
-add_action( 'login_form_bp-spam', 'bp_live_spammer_login_error' ); 
+add_action( 'login_form_bp-spam', 'bp_live_spammer_login_error' );
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-loader.php b/wp-content/plugins/buddypress/bp-members/bp-members-loader.php
index eae52b7317eaecdf0819d011509972e1243bb2e5..e04fb2564efc19554f4a1715f42e448eee8a5ed6 100644
--- a/wp-content/plugins/buddypress/bp-members/bp-members-loader.php
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-loader.php
@@ -18,11 +18,14 @@ class BP_Members_Component extends BP_Component {
 	 *
 	 * @since BuddyPress (1.5)
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'members',
 			__( 'Members', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 20
+			)
 		);
 	}
 
@@ -34,6 +37,7 @@ class BP_Members_Component extends BP_Component {
 	public function includes( $includes = array() ) {
 		$includes = array(
 			'actions',
+			'classes',
 			'filters',
 			'screens',
 			'template',
@@ -42,6 +46,11 @@ class BP_Members_Component extends BP_Component {
 			'functions',
 			'notifications',
 		);
+
+		if ( is_admin() ) {
+			$includes[] = 'admin';
+		}
+
 		parent::includes( $includes );
 	}
 
@@ -52,23 +61,27 @@ class BP_Members_Component extends BP_Component {
 	 * backwards compatibility.
 	 *
 	 * @since BuddyPress (1.5)
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_globals( $args = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		// Define a slug, if necessary
 		if ( !defined( 'BP_MEMBERS_SLUG' ) )
 			define( 'BP_MEMBERS_SLUG', $this->id );
 
-		$globals = array(
+		$members_globals = array(
 			'slug'          => BP_MEMBERS_SLUG,
 			'root_slug'     => isset( $bp->pages->members->slug ) ? $bp->pages->members->slug : BP_MEMBERS_SLUG,
 			'has_directory' => true,
+			'directory_title' => _x( 'Members', 'component directory title', 'buddypress' ),
+			'global_tables' => array(
+				'table_name_last_activity' => bp_core_get_table_prefix() . 'bp_activity',
+				'table_name_signups'       => bp_core_get_table_prefix() . 'signups',
+			),
 			'search_string' => __( 'Search Members...', 'buddypress' ),
 		);
 
-		parent::setup_globals( $globals );
+		parent::setup_globals( $members_globals );
 
 		/** Logged in user ****************************************************/
 
@@ -95,6 +108,9 @@ class BP_Members_Component extends BP_Component {
 		// Fetch the full name displayed user
 		$bp->displayed_user->fullname = bp_core_get_user_displayname( bp_displayed_user_id() );
 
+		/** Signup ***************************************************/
+		$bp->signup = new stdClass;
+
 		/** Profiles Fallback *************************************************/
 
 		if ( !bp_is_active( 'xprofile' ) ) {
@@ -104,11 +120,13 @@ class BP_Members_Component extends BP_Component {
 		}
 
 		/** Default Profile Component *****************************************/
+
 		if ( !defined( 'BP_DEFAULT_COMPONENT' ) ) {
-			if ( bp_is_active( 'activity' ) && isset( $bp->pages->activity ) )
+			if ( bp_is_active( 'activity' ) && isset( $bp->pages->activity ) ) {
 				$bp->default_component = bp_get_activity_slug();
-			else
-				$bp->default_component = ( 'xprofile' == $bp->profile->id ) ? 'profile' : $bp->profile->id;
+			} else {
+				$bp->default_component = ( 'xprofile' === $bp->profile->id ) ? 'profile' : $bp->profile->id;
+			}
 
 		} else {
 			$bp->default_component = BP_DEFAULT_COMPONENT;
@@ -135,25 +153,33 @@ class BP_Members_Component extends BP_Component {
 				// The canonical URL will not contain the default component
 				unset( $bp->canonical_stack['component'] );
 			}
+
+			// if we're on a spammer's profile page, only users with the 'bp_moderate' cap
+			// can view subpages on the spammer's profile
+			//
+			// users without the cap trying to access a spammer's subnav page will get
+			// redirected to the root of the spammer's profile page.  this occurs by
+			// by removing the component in the canonical stack.
+			if ( bp_is_user_spammer( bp_displayed_user_id() ) && ! bp_current_user_can( 'bp_moderate' ) ) {
+				unset( $bp->canonical_stack['component'] );
+			}
 		}
 	}
 
 	/**
 	 * Setup BuddyBar navigation
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		// Add 'Profile' to the main navigation
 		if ( !bp_is_active( 'xprofile' ) ) {
 
 			// Don't set up navigation if there's no user
-			if ( !is_user_logged_in() && !bp_is_user() )
+			if ( !is_user_logged_in() && !bp_is_user() ) {
 				return;
+			}
 
-			$sub_nav  = array();
 			$main_nav = array(
 				'name'                => __( 'Profile', 'buddypress' ),
 				'slug'                => $bp->profile->slug,
@@ -164,8 +190,8 @@ class BP_Members_Component extends BP_Component {
 			);
 
 			// User links
-			$user_domain   = bp_displayed_user_domain() ? bp_displayed_user_domain() : bp_loggedin_user_domain();
-			$profile_link  = trailingslashit( $user_domain . $bp->profile->slug );
+			$user_domain  = bp_displayed_user_domain() ? bp_displayed_user_domain() : bp_loggedin_user_domain();
+			$profile_link = trailingslashit( $user_domain . $bp->profile->slug );
 
 			// Add the subnav items to the profile
 			$sub_nav[] = array(
@@ -186,8 +212,8 @@ class BP_Members_Component extends BP_Component {
 	 *
 	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
-	function setup_title() {
-		global $bp;
+	public function setup_title() {
+		$bp = buddypress();
 
 		if ( bp_is_my_profile() ) {
 			$bp->bp_options_title = __( 'You', 'buddypress' );
@@ -205,7 +231,6 @@ class BP_Members_Component extends BP_Component {
 }
 
 function bp_setup_members() {
-	global $bp;
-	$bp->members = new BP_Members_Component();
+	buddypress()->members = new BP_Members_Component();
 }
 add_action( 'bp_setup_components', 'bp_setup_members', 1 );
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-notifications.php b/wp-content/plugins/buddypress/bp-members/bp-members-notifications.php
index 5e670b771606f09a1e9238b33033b1cb87b2e19f..703be51006e5696ac4c4177ef5705d0e426ddfd2 100644
--- a/wp-content/plugins/buddypress/bp-members/bp-members-notifications.php
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-notifications.php
@@ -3,7 +3,8 @@
 /**
  * BuddyPress Member Notifications
  *
- * Functions and filters used for member notification
+ * Backwards compatibility functions and filters used for member notifications.
+ * Use bp-notifications instead.
  *
  * @package BuddyPress
  * @subpackage MembersNotifications
@@ -15,6 +16,9 @@ if ( !defined( 'ABSPATH' ) ) exit;
 /**
  * Add a notification for a specific user, from a specific component
  *
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_add_notification() instead.
+ *
  * @since BuddyPress (1.0)
  * @param string $item_id
  * @param int $user_id
@@ -22,161 +26,120 @@ if ( !defined( 'ABSPATH' ) ) exit;
  * @param string $component_action
  * @param string $secondary_item_id
  * @param string $date_notified
+ * @param int $is_new
  * @return boolean True on success, false on fail
  */
-function bp_core_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false ) {
-
-	if ( empty( $date_notified ) )
-		$date_notified = bp_core_current_time();
+function bp_core_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false, $is_new = 1 ) {
 
-	$notification                   = new BP_Core_Notification;
-	$notification->item_id          = $item_id;
-	$notification->user_id          = $user_id;
-	$notification->component_name   = $component_name;
-	$notification->component_action = $component_action;
-	$notification->date_notified    = $date_notified;
-	$notification->is_new           = 1;
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return false;
+	}
 
-	if ( !empty( $secondary_item_id ) )
-		$notification->secondary_item_id = $secondary_item_id;
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_add_notification()' );
 
-	if ( $notification->save() )
-		return true;
+	// Notifications must always have a time
+	if ( false === $date_notified ) {
+		$date_notified = bp_core_current_time();
+	}
 
-	return false;
+	// Add the notification
+	return bp_notifications_add_notification( array(
+		'item_id'           => $item_id,
+		'user_id'           => $user_id,
+		'component_name'    => $component_name,
+		'component_action'  => $component_action,
+		'secondary_item_id' => $secondary_item_id,
+		'date_notified'     => $date_notified,
+		'is_new'            => $is_new
+	) );
 }
 
 /**
  * Delete a specific notification by its ID
  *
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_delete_notification() instead.
+ *
  * @since BuddyPress (1.0)
  * @param int $id
  * @return boolean True on success, false on fail
  */
 function bp_core_delete_notification( $id ) {
-	if ( !bp_core_check_notification_access( bp_loggedin_user_id(), $id ) )
+
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
 		return false;
+	}
 
-	return BP_Core_Notification::delete( $id );
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notification()' );
+
+	return BP_Notifications_Notification::delete_by_id( $id );
 }
 
 /**
  * Get a specific notification by its ID
  *
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_get_notification() instead.
+ *
  * @since BuddyPress (1.0)
  * @param int $id
  * @return BP_Core_Notification
  */
 function bp_core_get_notification( $id ) {
-	return new BP_Core_Notification( $id );
+
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return false;
+	}
+
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_get_notification()' );
+
+	return bp_notifications_get_notification( $id );
 }
 
 /**
  * Get notifications for a specific user
  *
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_get_notifications_for_user() instead.
+ *
  * @since BuddyPress (1.0)
  * @global BuddyPress $bp
  * @param int $user_id
  * @param string $format
  * @return boolean Object or array on success, false on fail
  */
-function bp_core_get_notifications_for_user( $user_id, $format = 'simple' ) {
-	global $bp;
-
-	$notifications         = BP_Core_Notification::get_all_for_user( $user_id );
-	$grouped_notifications = array(); // Notification groups
-	$renderable            = array(); // Renderable notifications
+function bp_core_get_notifications_for_user( $user_id, $format = 'string' ) {
 
-	// Group notifications by component and component_action and provide totals
-	for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) {
-		$notification = $notifications[$i];
-		$grouped_notifications[$notification->component_name][$notification->component_action][] = $notification;
-	}
-
-	// Bail if no notification groups
-	if ( empty( $grouped_notifications ) )
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
 		return false;
-
-	// Calculate a renderable output for each notification type
-	foreach ( $grouped_notifications as $component_name => $action_arrays ) {
-
-		// Skip if group is empty
-		if ( empty( $action_arrays ) )
-			continue;
-
-		// Skip inactive components
-		if ( !bp_is_active( $component_name ) )
-			continue;
-
-		// Loop through each actionable item and try to map it to a component
-		foreach ( (array) $action_arrays as $component_action_name => $component_action_items ) {
-
-			// Get the number of actionable items
-			$action_item_count = count( $component_action_items );
-
-			// Skip if the count is less than 1
-			if ( $action_item_count < 1 )
-				continue;
-
-			// Callback function exists
-			if ( isset( $bp->{$component_name}->notification_callback ) && is_callable( $bp->{$component_name}->notification_callback ) ) {
-
-				// Function should return an object
-				if ( 'object' == $format ) {
-
-					// Retrieve the content of the notification using the callback
-					$content = call_user_func(
-						$bp->{$component_name}->notification_callback,
-						$component_action_name,
-						$component_action_items[0]->item_id,
-						$component_action_items[0]->secondary_item_id,
-						$action_item_count,
-						'array'
-					);
-
-					// Create the object to be returned
-					$notification_object = new stdClass;
-
-					// Minimal backpat with non-compatible notification
-					// callback functions
-					if ( is_string( $content ) ) {
-						$notification_object->content = $content;
-						$notification_object->href    = bp_loggedin_user_domain();
-					} else {
-						$notification_object->content = $content['text'];
-						$notification_object->href    = $content['link'];
-					}
-
-					$notification_object->id = $component_action_items[0]->id;
-					$renderable[]            = $notification_object;
-
-				// Return an array of content strings
-				} else {
-					$content      = call_user_func( $bp->{$component_name}->notification_callback, $component_action_name, $component_action_items[0]->item_id, $component_action_items[0]->secondary_item_id, $action_item_count );
-					$renderable[] = $content;
-				}
-
-			// @deprecated format_notification_function - 1.5
-			} elseif ( isset( $bp->{$component_name}->format_notification_function ) && function_exists( $bp->{$component_name}->format_notification_function ) ) {
-				$renderable[] = call_user_func( $bp->{$component_name}->format_notification_function, $component_action_name, $component_action_items[0]->item_id, $component_action_items[0]->secondary_item_id, $action_item_count );
-			}
-		}
 	}
 
-	// If renderable is empty array, set to false
-	if ( empty( $renderable ) )
-		$renderable = false;
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_get_notifications_for_user()' );
+
+	$renderable = bp_notifications_get_notifications_for_user( $user_id, $format );
 
-	// Filter and return
 	return apply_filters( 'bp_core_get_notifications_for_user', $renderable, $user_id, $format );
 }
 
+/** Delete ********************************************************************/
+
 /**
  * Delete notifications for a user by type
  *
  * Used when clearing out notifications for a specific component when the user
  * has visited that component.
  *
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_delete_notifications_by_type() instead.
+ *
  * @since BuddyPress (1.0)
  * @param int $user_id
  * @param string $component_name
@@ -184,7 +147,16 @@ function bp_core_get_notifications_for_user( $user_id, $format = 'simple' ) {
  * @return boolean True on success, false on fail
  */
 function bp_core_delete_notifications_by_type( $user_id, $component_name, $component_action ) {
-	return BP_Core_Notification::delete_for_user_by_type( $user_id, $component_name, $component_action );
+
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return false;
+	}
+
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_by_type()' );
+
+	return bp_notifications_delete_notifications_by_type( $user_id, $component_name, $component_action );
 }
 
 /**
@@ -193,6 +165,9 @@ function bp_core_delete_notifications_by_type( $user_id, $component_name, $compo
  * Used when clearing out notifications for a specific component when the user
  * has visited that component.
  *
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_delete_notifications_by_item_id() instead.
+ *
  * @since BuddyPress (1.0)
  * @param int $user_id
  * @param string $component_name
@@ -200,13 +175,23 @@ function bp_core_delete_notifications_by_type( $user_id, $component_name, $compo
  * @return boolean True on success, false on fail
  */
 function bp_core_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false ) {
-	return BP_Core_Notification::delete_for_user_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id );
+
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return false;
+	}
+
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_by_item_id()' );
+
+	return bp_notifications_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id );
 }
 
 /**
  * Delete all notifications for by type
  *
- * Used when clearing out notifications for an entire component
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_delete_all_notifications_by_type() instead.
  *
  * @since BuddyPress (1.0)
  * @param int $user_id
@@ -215,7 +200,16 @@ function bp_core_delete_notifications_by_item_id( $user_id, $item_id, $component
  * @return boolean True on success, false on fail
  */
 function bp_core_delete_all_notifications_by_type( $item_id, $component_name, $component_action = false, $secondary_item_id = false ) {
-	return BP_Core_Notification::delete_all_by_type( $item_id, $component_name, $component_action, $secondary_item_id );
+
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return false;
+	}
+
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_all_notifications_by_type()' );
+
+	bp_notifications_delete_all_notifications_by_type( $item_id, $component_name, $component_action, $secondary_item_id );
 }
 
 /**
@@ -223,6 +217,9 @@ function bp_core_delete_all_notifications_by_type( $item_id, $component_name, $c
  *
  * Used when clearing out all notifications for a user, whene deleted or spammed
  *
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_delete_notifications_from_user() instead.
+ *
  * @since BuddyPress (1.0)
  * @param int $user_id
  * @param string $component_name
@@ -230,22 +227,42 @@ function bp_core_delete_all_notifications_by_type( $item_id, $component_name, $c
  * @return boolean True on success, false on fail
  */
 function bp_core_delete_notifications_from_user( $user_id, $component_name, $component_action ) {
-	return BP_Core_Notification::delete_from_user_by_type( $user_id, $component_name, $component_action );
+
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
+		return false;
+	}
+
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_from_user()' );
+
+	return bp_notifications_delete_notifications_from_user( $user_id, $component_name, $component_action );
 }
 
+/** Helpers *******************************************************************/
+
 /**
  * Check if a user has access to a specific notification
  *
  * Used before deleting a notification for a user
  *
+ * @deprecated Deprecated since BuddyPress 1.9.0. Use
+ *  bp_notifications_check_notification_access() instead.
+ *
  * @since BuddyPress (1.0)
  * @param int $user_id
  * @param int $notification_id
  * @return boolean True on success, false on fail
  */
 function bp_core_check_notification_access( $user_id, $notification_id ) {
-	if ( !BP_Core_Notification::check_access( $user_id, $notification_id ) )
+
+	// Bail if notifications is not active
+	if ( ! bp_is_active( 'notifications' ) ) {
 		return false;
+	}
+
+	// Trigger the deprecated function notice
+	_deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_check_notification_access()' );
 
-	return true;
+	return bp_notifications_check_notification_access( $user_id, $notification_id );
 }
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-screens.php b/wp-content/plugins/buddypress/bp-members/bp-members-screens.php
index dada9becb59d90baa7d0df1d2630e735beda7a05..d756ae1e1a67cc31b16223581363ce3b6fdef951 100644
--- a/wp-content/plugins/buddypress/bp-members/bp-members-screens.php
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-screens.php
@@ -35,7 +35,7 @@ function bp_members_screen_display_profile() {
  * @uses apply_filters()
  */
 function bp_members_screen_index() {
-	if ( !bp_is_user() && bp_is_members_component() ) {
+	if ( bp_is_members_directory() ) {
 		bp_update_is_directory( true, 'members' );
 
 		do_action( 'bp_members_screen_index' );
@@ -67,10 +67,6 @@ function bp_core_screen_signup() {
 		return;
 	}
 
-	if ( !isset( $bp->signup ) ) {
-		$bp->signup = new stdClass;
-	}
-
 	$bp->signup->step = 'request-details';
 
  	if ( !bp_get_signup_allowed() ) {
@@ -79,6 +75,8 @@ function bp_core_screen_signup() {
 	// If the signup page is submitted, validate and save
 	} elseif ( isset( $_POST['signup_submit'] ) && bp_verify_nonce_request( 'bp_new_signup' ) ) {
 
+		do_action( 'bp_signup_pre_validate' );
+
 		// Check the base account details for problems
 		$account_details = bp_core_validate_user_signup( $_POST['signup_username'], $_POST['signup_email'] );
 
@@ -228,6 +226,19 @@ function bp_core_screen_activation() {
 	if ( !bp_is_current_component( 'activate' ) )
 		return false;
 
+	// If the user is logged in, redirect away from here
+	if ( is_user_logged_in() ) {
+		if ( bp_is_component_front_page( 'activate' ) ) {
+			$redirect_to = trailingslashit( bp_get_root_domain() . '/' . bp_get_members_root_slug() );
+		} else {
+			$redirect_to = trailingslashit( bp_get_root_domain() );
+		}
+
+		bp_core_redirect( apply_filters( 'bp_loggedin_activate_page_redirect_to', $redirect_to ) );
+
+		return;
+	}
+
 	// Check if an activation key has been passed
 	if ( isset( $_GET['key'] ) ) {
 
@@ -240,11 +251,7 @@ function bp_core_screen_activation() {
 			bp_core_redirect( trailingslashit( bp_get_root_domain() . '/' . $bp->pages->activate->slug ) );
 		}
 
-		// Check for an uploaded avatar and move that to the correct user folder
-		if ( is_multisite() )
-			$hashed_key = wp_hash( $_GET['key'] );
-		else
-			$hashed_key = wp_hash( $user );
+		$hashed_key = wp_hash( $_GET['key'] );
 
 		// Check if the avatar folder exists. If it does, move rename it, move
 		// it and delete the signup avatar dir
@@ -352,13 +359,13 @@ class BP_Members_Theme_Compat {
 	public function directory_dummy_post() {
 		bp_theme_compat_reset_post( array(
 			'ID'             => 0,
-			'post_title'     => __( 'Members', 'buddypress' ),
+			'post_title'     => bp_get_directory_title( 'members' ),
 			'post_author'    => 0,
 			'post_date'      => 0,
 			'post_content'   => '',
 			'post_type'      => 'bp_members',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
@@ -369,13 +376,13 @@ class BP_Members_Theme_Compat {
 	 * @since BuddyPress (1.7)
 	 */
 	public function directory_content() {
-		bp_buffer_template_part( 'members/index' );
+		return bp_buffer_template_part( 'members/index', null, false );
 	}
 
 	/** Single ****************************************************************/
 
 	/**
-	 * Add custom template hierarchy to theme compat for member pages. 
+	 * Add custom template hierarchy to theme compat for member pages.
 	 *
 	 * This is to mirror how WordPress has {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
 	 *
@@ -385,8 +392,8 @@ class BP_Members_Theme_Compat {
 	 * @return array $templates Array of custom templates to look for.
 	 */
 	public function single_template_hierarchy( $templates ) {
-		// Setup some variables we're going to reference in our custom templates 
-		$user_nicename = buddypress()->displayed_user->userdata->user_nicename; 
+		// Setup some variables we're going to reference in our custom templates
+		$user_nicename = buddypress()->displayed_user->userdata->user_nicename;
 
 		// Setup our templates based on priority
 		$new_templates = apply_filters( 'bp_template_hierarchy_members_single_item', array(
@@ -418,7 +425,7 @@ class BP_Members_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => 'bp_members',
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
@@ -429,7 +436,7 @@ class BP_Members_Theme_Compat {
 	 * @since BuddyPress (1.7)
 	 */
 	public function single_dummy_content() {
-		bp_buffer_template_part( 'members/single/home' );
+		return bp_buffer_template_part( 'members/single/home', null, false );
 	}
 }
 new BP_Members_Theme_Compat();
@@ -534,7 +541,7 @@ class BP_Registration_Theme_Compat {
 			'post_content'   => '',
 			'post_type'      => $post_type,
 			'post_status'    => 'publish',
-			'is_archive'     => true,
+			'is_page'        => true,
 			'comment_status' => 'closed'
 		) );
 	}
@@ -546,9 +553,9 @@ class BP_Registration_Theme_Compat {
 	 */
 	public function dummy_content() {
 		if ( bp_is_register_page() ) {
-			bp_buffer_template_part( 'members/register' );
+			return bp_buffer_template_part( 'members/register', null, false );
 		} else {
-			bp_buffer_template_part( 'members/activate' );
+			return bp_buffer_template_part( 'members/activate', null, false );
 		}
 	}
 }
diff --git a/wp-content/plugins/buddypress/bp-members/bp-members-template.php b/wp-content/plugins/buddypress/bp-members/bp-members-template.php
index a1c5080b7467d68a6ea858bfe3bc0b647cd3195c..57416933720e7c811084598d035a3e56e63ff1af 100644
--- a/wp-content/plugins/buddypress/bp-members/bp-members-template.php
+++ b/wp-content/plugins/buddypress/bp-members/bp-members-template.php
@@ -32,8 +32,7 @@ function bp_members_slug() {
 	 * @since BuddyPress (1.5)
 	 */
 	function bp_get_members_slug() {
-		global $bp;
-		return apply_filters( 'bp_get_members_slug', $bp->members->slug );
+		return apply_filters( 'bp_get_members_slug', buddypress()->members->slug );
 	}
 
 /**
@@ -56,8 +55,7 @@ function bp_members_root_slug() {
 	 * @since BuddyPress (1.5)
 	 */
 	function bp_get_members_root_slug() {
-		global $bp;
-		return apply_filters( 'bp_get_members_root_slug', $bp->members->root_slug );
+		return apply_filters( 'bp_get_members_root_slug', buddypress()->members->root_slug );
 	}
 
 /**
@@ -109,12 +107,13 @@ function bp_signup_slug() {
 	function bp_get_signup_slug() {
 		$bp = buddypress();
 
-		if ( !empty( $bp->pages->register->slug ) )
+		if ( !empty( $bp->pages->register->slug ) ) {
 			$slug = $bp->pages->register->slug;
-		elseif ( defined( 'BP_REGISTER_SLUG' ) )
+		} elseif ( defined( 'BP_REGISTER_SLUG' ) ) {
 			$slug = BP_REGISTER_SLUG;
-		else
+		} else {
 			$slug = 'register';
+		}
 
 		return apply_filters( 'bp_get_signup_slug', $slug );
 	}
@@ -139,14 +138,15 @@ function bp_activate_slug() {
 	 * @since BuddyPress (1.5)
 	 */
 	function bp_get_activate_slug() {
-		global $bp;
+		$bp = buddypress();
 
-		if ( !empty( $bp->pages->activate->slug ) )
+		if ( !empty( $bp->pages->activate->slug ) ) {
 			$slug = $bp->pages->activate->slug;
-		elseif ( defined( 'BP_ACTIVATION_SLUG' ) )
+		} elseif ( defined( 'BP_ACTIVATION_SLUG' ) ) {
 			$slug = BP_ACTIVATION_SLUG;
-		else
+		} else {
 			$slug = 'activate';
+		}
 
 		return apply_filters( 'bp_get_activate_slug', $slug );
 	}
@@ -300,7 +300,7 @@ function bp_has_members( $args = '' ) {
 		'populate_extras' => true           // Fetch usermeta? Friend count, last active etc.
 	);
 
-	$r = wp_parse_args( $args, $defaults );
+	$r = bp_parse_args( $args, $defaults, 'has_members' );
 	extract( $r );
 
 	// Pass a filter if ?s= is set.
@@ -344,13 +344,13 @@ function bp_members_pagination_count() {
 		$total     = bp_core_number_format( $members_template->total_member_count );
 
 		if ( 'active' == $members_template->type )
-			$pag = sprintf( __( 'Viewing member %1$s to %2$s (of %3$s active members)', 'buddypress' ), $from_num, $to_num, $total );
+			$pag = sprintf( _n( 'Viewing member %1$s to %2$s (of %3$s active member)', 'Viewing member %1$s to %2$s (of %3$s active members)', $total, 'buddypress' ), $from_num, $to_num, $total );
 		else if ( 'popular' == $members_template->type )
-			$pag = sprintf( __( 'Viewing member %1$s to %2$s (of %3$s members with friends)', 'buddypress' ), $from_num, $to_num, $total );
+			$pag = sprintf( _n( 'Viewing member %1$s to %2$s (of %3$s member with friends)', 'Viewing member %1$s to %2$s (of %3$s members with friends)', $total, 'buddypress' ), $from_num, $to_num, $total );
 		else if ( 'online' == $members_template->type )
-			$pag = sprintf( __( 'Viewing member %1$s to %2$s (of %3$s members online)', 'buddypress' ), $from_num, $to_num, $total );
+			$pag = sprintf( _n( 'Viewing member %1$s to %2$s (of %3$s member online)', 'Viewing member %1$s to %2$s (of %3$s members online)', $total, 'buddypress' ), $from_num, $to_num, $total );
 		else
-			$pag = sprintf( __( 'Viewing member %1$s to %2$s (of %3$s members)', 'buddypress' ), $from_num, $to_num, $total );
+			$pag = sprintf( _n( 'Viewing member %1$s to %2$s (of %3$s member)', 'Viewing member %1$s to %2$s (of %3$s members)', $total, 'buddypress' ), $from_num, $to_num, $total );
 
 		return apply_filters( 'bp_members_pagination_count', $pag );
 	}
@@ -586,16 +586,40 @@ function bp_member_name() {
 	add_filter( 'bp_get_member_name', 'strip_tags'     );
 	add_filter( 'bp_get_member_name', 'esc_html'       );
 
-function bp_member_last_active() {
-	echo bp_get_member_last_active();
+/**
+ * Output the current member's last active time.
+ *
+ * @param array $args See {@link bp_get_member_last_active()}.
+ */
+function bp_member_last_active( $args = array() ) {
+	echo bp_get_member_last_active( $args );
 }
-	function bp_get_member_last_active() {
+	/**
+	 * Return the current member's last active time.
+	 *
+	 * @param array $args {
+	 *     Array of optional arguments.
+	 *     @type bool $active_format If true, formatted "Active 5 minutes
+	 *           ago". If false, formatted "5 minutes ago". Default: true.
+	 * }
+	 * @return string
+	 */
+	function bp_get_member_last_active( $args = array() ) {
 		global $members_template;
 
-		if ( isset( $members_template->member->last_activity ) )
-			$last_activity = bp_core_get_last_activity( $members_template->member->last_activity, __( 'active %s', 'buddypress' ) );
-		else
+		$r = wp_parse_args( $args, array(
+			'active_format' => true,
+		) );
+
+		if ( isset( $members_template->member->last_activity ) ) {
+			if ( ! empty( $r['active_format'] ) ) {
+				$last_activity = bp_core_get_last_activity( $members_template->member->last_activity, __( 'active %s', 'buddypress' ) );
+			} else {
+				$last_activity = bp_core_time_since( $members_template->member->last_activity );
+			}
+		} else {
 			$last_activity = __( 'Never active', 'buddypress' );
+		}
 
 		return apply_filters( 'bp_member_last_active', $last_activity );
 	}
@@ -630,40 +654,77 @@ function bp_member_latest_update( $args = '' ) {
 		return apply_filters( 'bp_get_member_latest_update', $update_content );
 	}
 
+/**
+ * Output a piece of user profile data.
+ *
+ * @see bp_get_member_profile_data() for a description of params.
+ *
+ * @param array $args See {@link bp_get_member_profile_data()}.
+ */
 function bp_member_profile_data( $args = '' ) {
 	echo bp_get_member_profile_data( $args );
 }
+	/**
+	 * Get a piece of user profile data.
+	 *
+	 * When used in a bp_has_members() loop, this function will attempt
+	 * to fetch profile data cached in the template global. It is also safe
+	 * to use outside of the loop.
+	 *
+	 * @param array $args {
+	 *     Array of config paramaters.
+	 *     @type string $field Name of the profile field.
+	 *     @type int $user_id ID of the user whose data is being fetched.
+	 *           Defaults to the current member in the loop, or if not
+	 *           present, to the currently displayed user.
+	 * }
+	 * @return string|bool Profile data if found, otherwise false.
+	 */
 	function bp_get_member_profile_data( $args = '' ) {
 		global $members_template;
 
-		if ( !bp_is_active( 'xprofile' ) )
+		if ( ! bp_is_active( 'xprofile' ) ) {
 			return false;
+		}
 
 		// Declare local variables
-		$data    = false;
-		$user_id = 0;
+		$data = false;
 
 		// Guess at default $user_id
-		if ( !empty( $members_template->member->id ) )
-			$user_id = $members_template->member->id;
-		elseif ( bp_displayed_user_id() )
-			$user_id = bp_displayed_user_id();
+		$default_user_id = 0;
+		if ( ! empty( $members_template->member->id ) ) {
+			$default_user_id = $members_template->member->id;
+		} elseif ( bp_displayed_user_id() ) {
+			$default_user_id = bp_displayed_user_id();
+		}
 
 		$defaults = array(
-			'field'   => false,   // Field name
-			'user_id' => $user_id
+			'field'   => false,
+			'user_id' => $default_user_id,
 		);
 
 		$r = wp_parse_args( $args, $defaults );
-		extract( $r, EXTR_SKIP );
 
-		// Populate the user if it hasn't been already.
-		if ( empty( $members_template->member->profile_data ) && method_exists( 'BP_XProfile_ProfileData', 'get_all_for_user' ) )
-			$members_template->member->profile_data = BP_XProfile_ProfileData::get_all_for_user( $user_id );
+		// If we're in a members loop, get the data from the global
+		if ( ! empty( $members_template->member->profile_data ) ) {
+			$profile_data = $members_template->member->profile_data;
+		}
+
+		// Otherwise query for the data
+		if ( empty( $profile_data ) && method_exists( 'BP_XProfile_ProfileData', 'get_all_for_user' ) ) {
+			$profile_data = BP_XProfile_ProfileData::get_all_for_user( $r['user_id'] );
+		}
 
-		// Get the field data if there is data to get
-		if ( ! empty( $members_template->member->profile_data ) && ! empty( $members_template->member->profile_data[$field]['field_type'] ) && ! empty( $members_template->member->profile_data[$field]['field_data'] ) )
-			$data = xprofile_format_profile_field( $members_template->member->profile_data[$field]['field_type'], $members_template->member->profile_data[$field]['field_data'] );
+		// If we're in the members loop, but the profile data has not
+		// been loaded into the global, cache it there for later use
+		if ( ! empty( $members_template->member ) && empty( $members_template->member->profile_data ) ) {
+			$members_template->member->profile_data = $profile_data;
+		}
+
+		// Get the data for the specific field requested
+		if ( ! empty( $profile_data ) && ! empty( $profile_data[ $r['field'] ]['field_type'] ) && ! empty( $profile_data[ $r['field'] ]['field_data'] ) ) {
+			$data = xprofile_format_profile_field( $profile_data[ $r['field'] ]['field_type'], $profile_data[ $r['field'] ]['field_data'] );
+		}
 
 		return apply_filters( 'bp_get_member_profile_data', $data );
 	}
@@ -703,14 +764,14 @@ function bp_member_hidden_fields() {
 function bp_directory_members_search_form() {
 
 	$default_search_value = bp_get_search_default_text( 'members' );
-	$search_value         = !empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : $default_search_value; ?>
+	$search_value         = !empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : $default_search_value;
 
-	<form action="" method="get" id="search-members-form">
-		<label><input type="text" name="s" id="members_search" placeholder="<?php echo esc_attr( $search_value ) ?>" /></label>
-		<input type="submit" id="members_search_submit" name="members_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
-	</form>
+	$search_form_html = '<form action="" method="get" id="search-members-form">
+		<label><input type="text" name="s" id="members_search" placeholder="'. esc_attr( $search_value ) .'" /></label>
+		<input type="submit" id="members_search_submit" name="members_search_submit" value="' . __( 'Search', 'buddypress' ) . '" />
+	</form>';
 
-<?php
+	echo apply_filters( 'bp_directory_members_search_form', $search_form_html );
 }
 
 function bp_total_site_member_count() {
@@ -868,7 +929,7 @@ function bp_last_activity( $user_id = 0 ) {
 		if ( empty( $user_id ) )
 			$user_id = bp_displayed_user_id();
 
-		$last_activity = bp_core_get_last_activity( bp_get_user_meta( $user_id, 'last_activity', true ), __('active %s', 'buddypress') );
+		$last_activity = bp_core_get_last_activity( bp_get_user_last_activity( $user_id ), __('active %s', 'buddypress') );
 
 		return apply_filters( 'bp_get_last_activity', $last_activity );
 	}
@@ -1138,7 +1199,7 @@ function bp_signup_avatar( $args = '' ) {
 	echo bp_get_signup_avatar( $args );
 }
 	function bp_get_signup_avatar( $args = '' ) {
-		global $bp;
+		$bp = buddypress();
 
 		$defaults = array(
 			'size' => bp_core_avatar_full_width(),
@@ -1169,7 +1230,7 @@ function bp_signup_avatar( $args = '' ) {
 			if ( empty( $bp->grav_default->user ) )
 				$default_grav = 'wavatar';
 			else if ( 'mystery' == $bp->grav_default->user )
-				$default_grav = BP_PLUGIN_URL . 'bp-core/images/mystery-man.jpg';
+				$default_grav = $bp->plugin_url . 'bp-core/images/mystery-man.jpg';
 			else
 				$default_grav = $bp->grav_default->user;
 
diff --git a/wp-content/plugins/buddypress/bp-messages/bp-messages-cache.php b/wp-content/plugins/buddypress/bp-messages/bp-messages-cache.php
index c50b0282b2ce096c4f0150da7ea3d97dae793827..714c029cf2c24b5bcbda23ab19f0a6b1757b8fec 100644
--- a/wp-content/plugins/buddypress/bp-messages/bp-messages-cache.php
+++ b/wp-content/plugins/buddypress/bp-messages/bp-messages-cache.php
@@ -22,3 +22,43 @@ add_action( 'messages_message_sent',   'bp_core_clear_cache' );
 add_action( 'messages_screen_compose', 'bp_core_clear_cache' );
 add_action( 'messages_screen_sentbox', 'bp_core_clear_cache' );
 add_action( 'messages_screen_inbox',   'bp_core_clear_cache' );
+
+/**
+ * Clears unread count cache for each recipient after a message is sent.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param BP_Messages_Message $message
+ */
+function bp_messages_clear_unread_count_cache_on_message_save( BP_Messages_Message $message ) {
+	foreach ( (array) $message->recipients as $recipient ) {
+		wp_cache_delete( $recipient->user_id, 'bp_messages_unread_count' );
+	}
+}
+add_action( 'messages_message_after_save', 'bp_messages_clear_unread_count_cache_on_message_save' );
+
+/**
+ * Clears unread count cache for the logged-in user after a message is deleted.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int|array $thread_ids If single thread, the thread ID. Otherwise, an
+ *  array of thread IDs
+ */
+function bp_messages_clear_unread_count_cache_on_message_delete( $thread_ids ) {
+	wp_cache_delete( bp_loggedin_user_id(), 'bp_messages_unread_count' );
+}
+add_action( 'messages_before_delete_thread', 'bp_messages_clear_unread_count_cache_on_message_delete' );
+
+/**
+ * Invalidates cache for notices.
+ * 
+ * Currently, invalidates active notice cache.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_notices_clear_cache( $notice ) {
+	wp_cache_delete( 'active_notice', 'bp_messages' );
+}
+add_action( 'messages_notice_after_save',    'bp_notices_clear_cache' );
+add_action( 'messages_notice_before_delete', 'bp_notices_clear_cache' );
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-messages/bp-messages-classes.php b/wp-content/plugins/buddypress/bp-messages/bp-messages-classes.php
index 78841c5718aef96c472d3d3dc65167b299f196b3..6026dbd66b578da1d6af3e8b88b4b6abdc1a1176 100644
--- a/wp-content/plugins/buddypress/bp-messages/bp-messages-classes.php
+++ b/wp-content/plugins/buddypress/bp-messages/bp-messages-classes.php
@@ -10,18 +10,56 @@
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * BuddyPress Message Thread class.
+ *
+ * @since BuddyPress (1.0.0)
+ */
 class BP_Messages_Thread {
-	var $thread_id;
-	var $messages;
-	var $recipients;
-	var $sender_ids;
+	/**
+	 * The message thread ID.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 * @var int
+	 */
+	public $thread_id;
 
-	var $unread_count;
+	/**
+	 * The current messages.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 * @var object
+	 */
+	public $messages;
+
+	/**
+	 * The current recipients in the message thread.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 * @var object
+	 */
+	public $recipients;
+
+	/**
+	 * The user IDs of all messages in the message thread.
+	 *
+	 * @since BuddyPress (1.2.0)
+	 * @var array
+	 */
+	public $sender_ids;
+
+	/**
+	 * The unread count for the logged-in user.
+	 *
+	 * @since BuddyPress (1.2.0)
+	 * @var int
+	 */
+	public $unread_count;
 
 	/**
 	 * The content of the last message in this thread
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var string
 	 */
 	public $last_message_content;
@@ -29,7 +67,7 @@ class BP_Messages_Thread {
 	/**
 	 * The date of the last message in this thread
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var string
 	 */
 	public $last_message_date;
@@ -37,7 +75,7 @@ class BP_Messages_Thread {
 	/**
 	 * The ID of the last message in this thread
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var int
 	 */
 	public $last_message_id;
@@ -45,7 +83,7 @@ class BP_Messages_Thread {
 	/**
 	 * The subject of the last message in this thread
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var string
 	 */
 	public $last_message_subject;
@@ -53,7 +91,7 @@ class BP_Messages_Thread {
 	/**
 	 * The user ID of the author of the last message in this thread
 	 *
-	 * @since BuddyPress (1.2)
+	 * @since BuddyPress (1.2.0)
 	 * @var int
 	 */
 	public $last_sender_id;
@@ -61,48 +99,92 @@ class BP_Messages_Thread {
 	/**
 	 * Sort order of the messages in this thread (ASC or DESC).
 	 *
-	 * @since BuddyPress (1.5)
+	 * @since BuddyPress (1.5.0)
 	 * @var string
 	 */
 	public $messages_order;
 
-	function __construct( $thread_id = false, $order = 'ASC' ) {
-		if ( $thread_id )
+	/**
+	 * Constructor.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID.
+	 * @param string $order The order to sort the messages. Either 'ASC' or 'DESC'.
+	 */
+	public function __construct( $thread_id = false, $order = 'ASC' ) {
+		if ( $thread_id ) {
 			$this->populate( $thread_id, $order );
+		}
 	}
 
-	function populate( $thread_id, $order ) {
+	/**
+	 * Populate method.
+	 *
+	 * Used in constructor.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID.
+	 * @param string $order The order to sort the messages. Either 'ASC' or 'DESC'.
+	 */
+	public function populate( $thread_id, $order ) {
 		global $wpdb, $bp;
 
-		if( 'ASC' != $order && 'DESC' != $order )
+		if( 'ASC' != $order && 'DESC' != $order ) {
 			$order= 'ASC';
+		}
 
 		$this->messages_order = $order;
 		$this->thread_id      = $thread_id;
 
-		if ( !$this->messages = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_messages} WHERE thread_id = %d ORDER BY date_sent " . $order, $this->thread_id ) ) )
+		if ( !$this->messages = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_messages} WHERE thread_id = %d ORDER BY date_sent " . $order, $this->thread_id ) ) ) {
 			return false;
+		}
 
-		foreach ( (array) $this->messages as $key => $message )
+		foreach ( (array) $this->messages as $key => $message ) {
 			$this->sender_ids[$message->sender_id] = $message->sender_id;
+		}
 
 		// Fetch the recipients
 		$this->recipients = $this->get_recipients();
 
 		// Get the unread count for the logged in user
-		if ( isset( $this->recipients[bp_loggedin_user_id()] ) )
+		if ( isset( $this->recipients[bp_loggedin_user_id()] ) ) {
 			$this->unread_count = $this->recipients[bp_loggedin_user_id()]->unread_count;
+		}
 	}
 
-	function mark_read() {
+	/**
+	 * Mark a thread initialized in this class as read.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @see BP_Messages_Thread::mark_as_read()
+	 */
+	public function mark_read() {
 		BP_Messages_Thread::mark_as_read( $this->thread_id );
 	}
 
-	function mark_unread() {
+	/**
+	 * Mark a thread initialized in this class as unread.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @see BP_Messages_Thread::mark_as_unread()
+	 */
+	public function mark_unread() {
 		BP_Messages_Thread::mark_as_unread( $this->thread_id );
 	}
 
-	function get_recipients() {
+	/**
+	 * Returns recipients for a message thread.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @return object
+	 */
+	public function get_recipients() {
 		global $wpdb, $bp;
 
 		$recipients = array();
@@ -114,12 +196,24 @@ class BP_Messages_Thread {
 		return $recipients;
 	}
 
-	/** Static Functions **/
+	/** Static Functions ******************************************************/
 
-	function delete( $thread_id ) {
+	/**
+	 * Delete a message thread.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID
+	 * @return bool
+	 */
+	public static function delete( $thread_id ) {
 		global $wpdb, $bp;
 
-		$delete_for_user = $wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET is_deleted = 1 WHERE thread_id = %d AND user_id = %d", $thread_id, bp_loggedin_user_id() ) );
+		// Mark messages as deleted
+		$wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET is_deleted = 1 WHERE thread_id = %d AND user_id = %d", $thread_id, bp_loggedin_user_id() ) );
+
+		// Get the message id in order to pass to the action
+		$message_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) );
 
 		// Check to see if any more recipients remain for this message
 		// if not, then delete the message from the database.
@@ -133,22 +227,41 @@ class BP_Messages_Thread {
 			$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d", $thread_id ) );
 		}
 
+		do_action( 'messages_thread_deleted_thread', $message_id );
+
 		return true;
 	}
 
-	function get_current_threads_for_user( $user_id, $box = 'inbox', $type = 'all', $limit = null, $page = null, $search_terms = '' ) {
+	/**
+	 * Get current message threads for a user.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int    $user_id The user ID.
+	 * @param string $box  The type of mailbox to get. Either 'inbox' or 'sentbox'.
+	 *                     Defaults to 'inbox'.
+	 * @param string $type The type of messages to get. Either 'all' or 'unread'
+	 *                     or 'read'. Defaults to 'all'.
+	 * @param int    $limit The number of messages to get. Defaults to null.
+	 * @param int    $page  The page number to get. Defaults to null.
+	 * @param string $search_terms The search term to use. Defaults to ''.
+	 * @return array|bool Array on success. Boolean false on failure.
+	 */
+	public static function get_current_threads_for_user( $user_id, $box = 'inbox', $type = 'all', $limit = null, $page = null, $search_terms = '' ) {
 		global $wpdb, $bp;
 
 		$pag_sql = $type_sql = $search_sql = '';
-		if ( $limit && $page )
+		if ( $limit && $page ) {
 			$pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
+		}
 
-		if ( $type == 'unread' )
+		if ( $type == 'unread' ) {
 			$type_sql = " AND r.unread_count != 0 ";
-		elseif ( $type == 'read' )
+		} elseif ( $type == 'read' ) {
 			$type_sql = " AND r.unread_count = 0 ";
+		}
 
-		if ( !empty( $search_terms ) ) {
+		if ( ! empty( $search_terms ) ) {
 			$search_terms = like_escape( esc_sql( $search_terms ) );
 			$search_sql   = "AND ( subject LIKE '%%$search_terms%%' OR message LIKE '%%$search_terms%%' )";
 		}
@@ -161,37 +274,70 @@ class BP_Messages_Thread {
 			$total_threads = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( DISTINCT m.thread_id ) FROM {$bp->messages->table_name_recipients} r, {$bp->messages->table_name_messages} m WHERE m.thread_id = r.thread_id AND r.is_deleted = 0 AND r.user_id = %d AND r.sender_only = 0 {$type_sql} {$search_sql} ", $user_id ) );
 		}
 
-		if ( empty( $thread_ids ) )
+		if ( empty( $thread_ids ) ) {
 			return false;
+		}
 
 		// Sort threads by date_sent
-		foreach( (array) $thread_ids as $thread )
+		foreach( (array) $thread_ids as $thread ) {
 			$sorted_threads[$thread->thread_id] = strtotime( $thread->date_sent );
+		}
 
 		arsort( $sorted_threads );
 
 		$threads = false;
-		foreach ( (array) $sorted_threads as $thread_id => $date_sent )
+		foreach ( (array) $sorted_threads as $thread_id => $date_sent ) {
 			$threads[] = new BP_Messages_Thread( $thread_id );
+		}
 
 		return array( 'threads' => &$threads, 'total' => (int) $total_threads );
 	}
 
-	function mark_as_read( $thread_id ) {
+	/**
+	 * Mark a thread as read.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID.
+	 */
+	public static function mark_as_read( $thread_id ) {
 		global $wpdb, $bp;
 
 		$sql = $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET unread_count = 0 WHERE user_id = %d AND thread_id = %d", bp_loggedin_user_id(), $thread_id );
 		$wpdb->query($sql);
+
+		wp_cache_delete( bp_loggedin_user_id(), 'bp_messages_unread_count' );
 	}
 
-	function mark_as_unread( $thread_id ) {
+	/**
+	 * Mark a thread as unread.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID.
+	 */
+	public static function mark_as_unread( $thread_id ) {
 		global $wpdb, $bp;
 
 		$sql = $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET unread_count = 1 WHERE user_id = %d AND thread_id = %d", bp_loggedin_user_id(), $thread_id );
 		$wpdb->query($sql);
+
+		wp_cache_delete( bp_loggedin_user_id(), 'bp_messages_unread_count' );
 	}
 
-	function get_total_threads_for_user( $user_id, $box = 'inbox', $type = 'all' ) {
+	/**
+	 * Returns the total number of message threads for a user.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int    $user_id The user ID.
+	 * @param string $box  The type of mailbox to get. Either 'inbox' or 'sentbox'.
+	 *                     Defaults to 'inbox'.
+	 * @param string $type The type of messages to get. Either 'all' or 'unread'
+	 *                     or 'read'. Defaults to 'all'.
+	 * @return int
+	 */
+	public static function get_total_threads_for_user( $user_id, $box = 'inbox', $type = 'all' ) {
 		global $wpdb, $bp;
 
 		$exclude_sender = '';
@@ -206,57 +352,116 @@ class BP_Messages_Thread {
 		return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(thread_id) FROM {$bp->messages->table_name_recipients} WHERE user_id = %d AND is_deleted = 0{$exclude_sender} {$type_sql}", $user_id ) );
 	}
 
-	function user_is_sender( $thread_id ) {
+	/**
+	 * Determine if the logged-in user is a sender of any message in a thread.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID.
+	 * @param bool
+	 */
+	public static function user_is_sender( $thread_id ) {
 		global $wpdb, $bp;
 
 		$sender_ids = $wpdb->get_col( $wpdb->prepare( "SELECT sender_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) );
 
-		if ( !$sender_ids )
+		if ( ! $sender_ids ) {
 			return false;
+		}
 
 		return in_array( bp_loggedin_user_id(), $sender_ids );
 	}
 
-	function get_last_sender( $thread_id ) {
+	/**
+	 * Returns the userlink of the last sender in a message thread.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID.
+	 * @return string|bool The user link on success. Boolean false on failure.
+	 */
+	public static function get_last_sender( $thread_id ) {
 		global $wpdb, $bp;
 
-		if ( !$sender_id = $wpdb->get_var( $wpdb->prepare( "SELECT sender_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d GROUP BY sender_id ORDER BY date_sent LIMIT 1", $thread_id ) ) )
+		if ( ! $sender_id = $wpdb->get_var( $wpdb->prepare( "SELECT sender_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d GROUP BY sender_id ORDER BY date_sent LIMIT 1", $thread_id ) ) ) {
 			return false;
+		}
 
 		return bp_core_get_userlink( $sender_id, true );
 	}
 
-	function get_inbox_count( $user_id = 0 ) {
+	/**
+	 * Gets the unread message count for a user.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $user_id The user ID.
+	 * @return int
+	 */
+	public static function get_inbox_count( $user_id = 0 ) {
 		global $wpdb, $bp;
 
-		if ( empty( $user_id ) )
+		if ( empty( $user_id ) ) {
 			$user_id = bp_loggedin_user_id();
+		}
+
+		$unread_count = wp_cache_get( $user_id, 'bp_messages_unread_count' );
 
-		$sql = $wpdb->prepare( "SELECT SUM(unread_count) FROM {$bp->messages->table_name_recipients} WHERE user_id = %d AND is_deleted = 0 AND sender_only = 0", $user_id );
-		$unread_count = $wpdb->get_var( $sql );
+		if ( false === $unread_count ) {
+			$unread_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT SUM(unread_count) FROM {$bp->messages->table_name_recipients} WHERE user_id = %d AND is_deleted = 0 AND sender_only = 0", $user_id ) );
 
-		if ( empty( $unread_count ) || is_wp_error( $unread_count ) )
-			return 0;
+			wp_cache_set( $user_id, $unread_count, 'bp_messages_unread_count' );
+		}
 
 		return (int) $unread_count;
 	}
 
-	function check_access( $thread_id, $user_id = 0 ) {
+	/**
+	 * Checks whether a user is a part of a message thread discussion.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID.
+	 * @param int $user_id The user ID.
+	 * @return int The message ID on success.
+	 */
+	public static function check_access( $thread_id, $user_id = 0 ) {
 		global $wpdb, $bp;
 
 		if ( empty( $user_id ) )
 			$user_id = bp_loggedin_user_id();
 
-		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND user_id = %d", $thread_id, $user_id ) );
+		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND is_deleted = 0 AND user_id = %d", $thread_id, $user_id ) );
 	}
 
-	function is_valid( $thread_id ) {
+	/**
+	 * Checks whether a message thread exists.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param int $thread_id The message thread ID.
+	 * @return int The message thread ID on success.
+	 */
+	public static function is_valid( $thread_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->get_var( $wpdb->prepare( "SELECT thread_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d LIMIT 1", $thread_id ) );
 	}
 
-	function get_recipient_links( $recipients ) {
+	/**
+	 * Returns a string containing all the message recipient userlinks.
+	 *
+	 * String is comma-delimited.
+	 *
+	 * If a message thread has more than four users, the returned string is simply
+	 * "X Recipients" where "X" is the number of recipients in the message thread.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param object $recipients Object containing the message recipients.
+	 * @return string
+	 */
+	public static function get_recipient_links( $recipients ) {
 		if ( count( $recipients ) >= 5 )
 			return sprintf( __( '%s Recipients', 'buddypress' ), number_format_i18n( count( $recipients ) ) );
 
@@ -275,9 +480,15 @@ class BP_Messages_Thread {
 		return implode( ', ', (array) $recipient_links );
 	}
 
-	// Update Functions
-
-	function update_tables() {
+	/**
+	 * Upgrade method for the older BP message thread DB table.
+	 *
+	 * @since BuddyPress (1.2.0)
+	 *
+	 * @todo We should remove this.  No one is going to upgrade from v1.1, right?
+	 * @return bool
+	 */
+	public static function update_tables() {
 		global $wpdb, $bp;
 
 		$bp_prefix = bp_core_get_table_prefix();
@@ -285,8 +496,9 @@ class BP_Messages_Thread {
 		$threads   = $wpdb->get_results( "SELECT * FROM {$bp_prefix}bp_messages_threads" );
 
 		// Nothing to update, just return true to remove the table
-		if ( empty( $threads ) )
+		if ( empty( $threads ) ) {
 			return true;
+		}
 
 		foreach( (array) $threads as $thread ) {
 			$message_ids = maybe_unserialize( $thread->message_ids );
@@ -295,37 +507,39 @@ class BP_Messages_Thread {
 				$message_ids = implode( ',', $message_ids );
 
 				// Add the thread_id to the messages table
-				if ( !$wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_messages} SET thread_id = %d WHERE id IN ({$message_ids})", $thread->id ) ) )
+				if ( ! $wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_messages} SET thread_id = %d WHERE id IN ({$message_ids})", $thread->id ) ) )
 					$errors = true;
 			}
 		}
 
-		if ( $errors )
+		if ( $errors ) {
 			return false;
+		}
 
 		return true;
 	}
 }
 
 class BP_Messages_Message {
-	var $id;
-	var $thread_id;
-	var $sender_id;
-	var $subject;
-	var $message;
-	var $date_sent;
+	public $id;
+	public $thread_id;
+	public $sender_id;
+	public $subject;
+	public $message;
+	public $date_sent;
 
-	var $recipients = false;
+	public $recipients = false;
 
-	function __construct( $id = null ) {
+	public function __construct( $id = null ) {
 		$this->date_sent = bp_core_current_time();
 		$this->sender_id = bp_loggedin_user_id();
 
-		if ( !empty( $id ) )
+		if ( !empty( $id ) ) {
 			$this->populate( $id );
+		}
 	}
 
-	function populate( $id ) {
+	public function populate( $id ) {
 		global $wpdb, $bp;
 
 		if ( $message = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_messages} WHERE id = %d", $id ) ) ) {
@@ -338,7 +552,7 @@ class BP_Messages_Message {
 		}
 	}
 
-	function send() {
+	public function send() {
 		global $wpdb, $bp;
 
 		$this->sender_id = apply_filters( 'messages_message_sender_id_before_save', $this->sender_id, $this->id );
@@ -391,15 +605,14 @@ class BP_Messages_Message {
 		return $this->id;
 	}
 
-	function get_recipients() {
+	public function get_recipients() {
 		global $bp, $wpdb;
-
 		return $wpdb->get_results( $wpdb->prepare( "SELECT user_id FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d", $this->thread_id ) );
 	}
 
-	// Static Functions
+	/** Static Functions ******************************************************/
 
-	function get_recipient_ids( $recipient_usernames ) {
+	public static function get_recipient_ids( $recipient_usernames ) {
 		if ( !$recipient_usernames )
 			return false;
 
@@ -414,38 +627,85 @@ class BP_Messages_Message {
 		return $recipient_ids;
 	}
 
-	function get_last_sent_for_user( $thread_id ) {
+	public static function get_last_sent_for_user( $thread_id ) {
 		global $wpdb, $bp;
-
 		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_messages} WHERE sender_id = %d AND thread_id = %d ORDER BY date_sent DESC LIMIT 1", bp_loggedin_user_id(), $thread_id ) );
 	}
 
-	function is_user_sender( $user_id, $message_id ) {
+	public static function is_user_sender( $user_id, $message_id ) {
 		global $wpdb, $bp;
 		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_messages} WHERE sender_id = %d AND id = %d", $user_id, $message_id ) );
 	}
 
-	function get_message_sender( $message_id ) {
+	public static function get_message_sender( $message_id ) {
 		global $wpdb, $bp;
 		return $wpdb->get_var( $wpdb->prepare( "SELECT sender_id FROM {$bp->messages->table_name_messages} WHERE id = %d", $message_id ) );
 	}
 }
 
+/**
+ * BuddyPress Notices class.
+ *
+ * Use this class to create, activate, deactivate or delete notices.
+ *
+ * @since BuddyPress (1.0.0)
+ */
 class BP_Messages_Notice {
-	var $id = null;
-	var $subject;
-	var $message;
-	var $date_sent;
-	var $is_active;
+	/**
+	 * The notice ID.
+	 *
+	 * @var int
+	 */
+	public $id = null;
+
+	/**
+	 * The subject line for the notice.
+	 *
+	 * @var string
+	 */
+	public $subject;
+
+	/**
+	 * The content of the notice.
+	 *
+	 * @var string
+	 */
+	public $message;
+
+	/**
+	 * The date the notice was created.
+	 *
+	 * @var string
+	 */
+	public $date_sent;
+
+	/**
+	 * Whether the notice is active or not.
+	 *
+	 * @var int
+	 */
+	public $is_active;
 
-	function __construct( $id = null ) {
+	/**
+	 * Constructor.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 */
+	public function __construct( $id = null ) {
 		if ( $id ) {
 			$this->id = $id;
-			$this->populate($id);
+			$this->populate();
 		}
 	}
 
-	function populate() {
+	/**
+	 * Populate method.
+	 *
+	 * Runs during constructor.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 */
+	public function populate() {
 		global $wpdb, $bp;
 
 		$notice = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_notices} WHERE id = %d", $this->id ) );
@@ -458,7 +718,14 @@ class BP_Messages_Notice {
 		}
 	}
 
-	function save() {
+	/**
+	 * Saves a notice.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @return bool
+	 */
+	public function save() {
 		global $wpdb, $bp;
 
 		$this->subject = apply_filters( 'messages_notice_subject_before_save', $this->subject, $this->id );
@@ -466,77 +733,102 @@ class BP_Messages_Notice {
 
 		do_action_ref_array( 'messages_notice_before_save', array( &$this ) );
 
-		if ( empty( $this->id ) )
+		if ( empty( $this->id ) ) {
 			$sql = $wpdb->prepare( "INSERT INTO {$bp->messages->table_name_notices} (subject, message, date_sent, is_active) VALUES (%s, %s, %s, %d)", $this->subject, $this->message, $this->date_sent, $this->is_active );
-		else
+		} else {
 			$sql = $wpdb->prepare( "UPDATE {$bp->messages->table_name_notices} SET subject = %s, message = %s, is_active = %d WHERE id = %d", $this->subject, $this->message, $this->is_active, $this->id );
+		}
 
-		if ( !$wpdb->query( $sql ) )
+		if ( ! $wpdb->query( $sql ) ) {
 			return false;
+		}
 
-		if ( !$id = $this->id )
+		if ( ! $id = $this->id ) {
 			$id = $wpdb->insert_id;
+		}
 
 		// Now deactivate all notices apart from the new one.
 		$wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_notices} SET is_active = 0 WHERE id != %d", $id ) );
 
-		bp_update_user_meta( bp_loggedin_user_id(), 'last_activity', bp_core_current_time() );
+		bp_update_user_last_activity( bp_loggedin_user_id(), bp_core_current_time() );
 
 		do_action_ref_array( 'messages_notice_after_save', array( &$this ) );
 
 		return true;
 	}
 
-	function activate() {
+	/**
+	 * Activates a notice.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @return bool
+	 */
+	public function activate() {
 		$this->is_active = 1;
-		if ( !$this->save() )
-			return false;
-
-		return true;
+		return (bool) $this->save();
 	}
 
-	function deactivate() {
+	/**
+	 * Deactivates a notice.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @return bool
+	 */
+	public function deactivate() {
 		$this->is_active = 0;
-		if ( !$this->save() )
-			return false;
-
-		return true;
+		return (bool) $this->save();
 	}
 
-	function delete() {
+	/**
+	 * Deletes a notice.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @return bool
+	 */
+	public function delete() {
 		global $wpdb, $bp;
 
+		do_action( 'messages_notice_before_delete', $this );
+
 		$sql = $wpdb->prepare( "DELETE FROM {$bp->messages->table_name_notices} WHERE id = %d", $this->id );
 
-		if ( !$wpdb->query( $sql ) )
+		if ( ! $wpdb->query( $sql ) ) {
 			return false;
+		}
 
 		return true;
 	}
 
-	// Static Functions
+	/** Static Methods ********************************************************/
 
 	/**
-	 * Pulls up a list of notices
+	 * Pulls up a list of notices.
 	 *
 	 * To get all notices, pass a value of -1 to pag_num
 	 *
-	 * @param array $args See $defaults for explanation of accepted arguments
-	 * @return array $notices
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @param array $data {
+	 *     Array of parameters.
+	 *     @type int $pag_num Number of notices per page. Defaults to 20.
+	 *     @type int $pag_page The page number.  Defaults to 1.
+	 * }
+	 * @return array
 	 */
-	function get_notices( $args = array() ) {
+	public static function get_notices( $args = array() ) {
 		global $wpdb, $bp;
 
-		$defaults = array(
+		$r = wp_parse_args( $args, array(
 			'pag_num'  => 20, // Number of notices per page
 			'pag_page' => 1   // Page number
-		);
-		$r = wp_parse_args( $args, $defaults );
-		extract( $r );
+		) );
 
 		$limit_sql = '';
-		if ( (int) $pag_num >= 0 ) {
-			$limit_sql = $wpdb->prepare( "LIMIT %d, %d", (int) ( ( $pag_page - 1 ) * $pag_num ), (int) $pag_num );
+		if ( (int) $r['pag_num'] >= 0 ) {
+			$limit_sql = $wpdb->prepare( "LIMIT %d, %d", (int) ( ( $r['pag_page'] - 1 ) * $r['pag_num'] ), (int) $r['pag_num'] );
 		}
 
 		$notices = $wpdb->get_results( "SELECT * FROM {$bp->messages->table_name_notices} ORDER BY date_sent DESC {$limit_sql}" );
@@ -544,7 +836,14 @@ class BP_Messages_Notice {
 		return $notices;
 	}
 
-	function get_total_notice_count() {
+	/**
+	 * Returns the total number of recorded notices.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @return int
+	 */
+	public static function get_total_notice_count() {
 		global $wpdb, $bp;
 
 		$notice_count = $wpdb->get_var( "SELECT COUNT(id) FROM " . $bp->messages->table_name_notices );
@@ -552,11 +851,25 @@ class BP_Messages_Notice {
 		return $notice_count;
 	}
 
-	function get_active() {
-		global $wpdb, $bp;
+	/**
+	 * Returns the active notice that should be displayed on the frontend.
+	 *
+	 * @since BuddyPress (1.0.0)
+	 *
+	 * @return object The BP_Messages_Notice object
+	 */
+	public static function get_active() {
+		$notice = wp_cache_get( 'active_notice', 'bp_messages' );
 
-		$notice_id = $wpdb->get_var( "SELECT id FROM {$bp->messages->table_name_notices} WHERE is_active = 1" );
+		if ( false === $notice ) {
+			global $wpdb, $bp;
+
+			$notice_id = $wpdb->get_var( "SELECT id FROM {$bp->messages->table_name_notices} WHERE is_active = 1" );
+			$notice    = new BP_Messages_Notice( $notice_id );
+
+			wp_cache_set( 'active_notice', $notice, 'bp_messages' );
+		}
 
-		return new BP_Messages_Notice( $notice_id );
+		return $notice;
 	}
 }
diff --git a/wp-content/plugins/buddypress/bp-messages/bp-messages-cssjs.php b/wp-content/plugins/buddypress/bp-messages/bp-messages-cssjs.php
index e423793aa58fed76c08502ea60e20b8ee345078b..f60bdfbe3b1cdc4b3fa672a00d6ac3bd62c773ea 100644
--- a/wp-content/plugins/buddypress/bp-messages/bp-messages-cssjs.php
+++ b/wp-content/plugins/buddypress/bp-messages/bp-messages-cssjs.php
@@ -18,11 +18,12 @@ function messages_add_autocomplete_js() {
 	if ( bp_is_messages_component() && bp_is_current_action( 'compose' ) ) {
 		add_action( 'wp_head', 'messages_autocomplete_init_jsblock' );
 
+		$bp  = buddypress();
 		$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
-		wp_enqueue_script( 'bp-jquery-autocomplete',    BP_PLUGIN_URL . "bp-messages/js/autocomplete/jquery.autocomplete{$min}.js",   array( 'jquery' ), bp_get_version() );
-		wp_enqueue_script( 'bp-jquery-autocomplete-fb', BP_PLUGIN_URL . "bp-messages/js/autocomplete/jquery.autocompletefb{$min}.js", array(),           bp_get_version() );
-		wp_enqueue_script( 'bp-jquery-bgiframe',        BP_PLUGIN_URL . "bp-messages/js/autocomplete/jquery.bgiframe{$min}.js",       array(),           bp_get_version() );
-		wp_enqueue_script( 'bp-jquery-dimensions',      BP_PLUGIN_URL . "bp-messages/js/autocomplete/jquery.dimensions{$min}.js",     array(),           bp_get_version() );
+		wp_enqueue_script( 'bp-jquery-autocomplete',    $bp->plugin_url . "bp-messages/js/autocomplete/jquery.autocomplete{$min}.js",   array( 'jquery' ), bp_get_version() );
+		wp_enqueue_script( 'bp-jquery-autocomplete-fb', $bp->plugin_url . "bp-messages/js/autocomplete/jquery.autocompletefb{$min}.js", array(),           bp_get_version() );
+		wp_enqueue_script( 'bp-jquery-bgiframe',        $bp->plugin_url . "bp-messages/js/autocomplete/jquery.bgiframe{$min}.js",       array(),           bp_get_version() );
+		wp_enqueue_script( 'bp-jquery-dimensions',      $bp->plugin_url . "bp-messages/js/autocomplete/jquery.dimensions{$min}.js",     array(),           bp_get_version() );
 	}
 }
 add_action( 'bp_actions', 'messages_add_autocomplete_js' );
@@ -31,7 +32,7 @@ function messages_add_autocomplete_css() {
 
 	if ( bp_is_messages_component() && bp_is_current_action( 'compose' ) ) {
 		$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
-		wp_enqueue_style( 'bp-messages-autocomplete', BP_PLUGIN_URL . "bp-messages/css/autocomplete/jquery.autocompletefb{$min}.css", array(), bp_get_version() );
+		wp_enqueue_style( 'bp-messages-autocomplete', buddypress()->plugin_url . "bp-messages/css/autocomplete/jquery.autocompletefb{$min}.css", array(), bp_get_version() );
 
 		wp_print_styles();
 	}
diff --git a/wp-content/plugins/buddypress/bp-messages/bp-messages-functions.php b/wp-content/plugins/buddypress/bp-messages/bp-messages-functions.php
index 1b009c931d63eeadf8e1eccf7be723e1ad0ba3b0..f63a24d2f24b8f29414e98ff7111063494c86537 100644
--- a/wp-content/plugins/buddypress/bp-messages/bp-messages-functions.php
+++ b/wp-content/plugins/buddypress/bp-messages/bp-messages-functions.php
@@ -74,31 +74,26 @@ function messages_new_message( $args = '' ) {
 
 			$recipient_id = false;
 
-			// input was numeric
-			if ( is_numeric( $recipient ) ) {
-				// do a check against the user ID column first
-				if ( bp_core_get_core_userdata( (int) $recipient ) )
-					$recipient_id = (int) $recipient;
+			// check user_login / nicename columns first
+			// @see http://buddypress.trac.wordpress.org/ticket/5151
+			if ( bp_is_username_compatibility_mode() ) {
+				$recipient_id = bp_core_get_userid( urldecode( $recipient ) );
+			} else {
+				$recipient_id = bp_core_get_userid_from_nicename( $recipient );
+			}
 
-				// if that fails, check against the user_login / user_nicename column
-				else {
-					if ( bp_is_username_compatibility_mode() )
-						$recipient_id = bp_core_get_userid( (int) $recipient );
-					else
-						$recipient_id = bp_core_get_userid_from_nicename( (int) $recipient );
+			// check against user ID column if no match and if passed recipient is numeric
+			if ( ! $recipient_id && is_numeric( $recipient ) ) {
+				if ( bp_core_get_core_userdata( (int) $recipient ) ) {
+					$recipient_id = (int) $recipient;
 				}
-
-			} else {
-				if ( bp_is_username_compatibility_mode() )
-					$recipient_id = bp_core_get_userid( $recipient );
-				else
-					$recipient_id = bp_core_get_userid_from_nicename( $recipient );
 			}
 
-			if ( !$recipient_id )
+			if ( ! $recipient_id ) {
 				$invalid_recipients[] = $recipient;
-			else
+			} else {
 				$recipient_ids[] = (int) $recipient_id;
+			}
 		}
 
 		// Strip the sender from the recipient list if they exist
@@ -119,14 +114,6 @@ function messages_new_message( $args = '' ) {
 	}
 
 	if ( $message->send() ) {
-
-		// Send screen notifications to the recipients
-		foreach ( (array) $message->recipients as $recipient )
-			bp_core_add_notification( $message->id, $recipient->user_id, 'messages', 'new_message' );
-
-		// Send email notifications to the recipients
-		messages_notification_new_message( array( 'message_id' => $message->id, 'sender_id' => $message->sender_id, 'subject' => $message->subject, 'content' => $message->message, 'recipients' => $message->recipients, 'thread_id' => $message->thread_id) );
-
 		do_action_ref_array( 'messages_message_sent', array( &$message ) );
 
 		return $message->thread_id;
@@ -227,43 +214,3 @@ function messages_get_message_sender( $message_id ) {
 function messages_is_valid_thread( $thread_id ) {
 	return BP_Messages_Thread::is_valid( $thread_id );
 }
-
-/**
- * Format the BuddyBar/Toolbar notifications for the Messages component
- *
- * @package BuddyPress
- *
- * @param string $action The kind of notification being rendered
- * @param int $item_id The primary item id
- * @param int $secondary_item_id The secondary item id
- * @param int $total_items The total number of messaging-related notifications waiting for the user
- * @param string $format 'string' for BuddyBar-compatible notifications; 'array' for WP Toolbar
- */
-function messages_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
-
-	if ( 'new_message' == $action ) {
-		$link  = trailingslashit( bp_loggedin_user_domain() . bp_get_messages_slug() . '/inbox' );
-		$title = __( 'Inbox', 'buddypress' );
-
-		if ( (int) $total_items > 1 ) {
-			$text = sprintf( __('You have %d new messages', 'buddypress' ), (int) $total_items );
-			$filter = 'bp_messages_multiple_new_message_notification';
-		} else {
-			$text = sprintf( __('You have %d new message', 'buddypress' ), (int) $total_items );
-			$filter = 'bp_messages_single_new_message_notification';
-		}
-	}
-
-	if ( 'string' == $format ) {
-		$return = apply_filters( $filter, '<a href="' . $link . '" title="' . $title . '">' . $text . '</a>', (int) $total_items, $text, $link );
-	} else {
-		$return = apply_filters( $filter, array(
-			'text' => $text,
-			'link' => $link
-		), $link, (int) $total_items, $text, $link );
-	}
-
-	do_action( 'messages_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
-
-	return $return;
-}
diff --git a/wp-content/plugins/buddypress/bp-messages/bp-messages-loader.php b/wp-content/plugins/buddypress/bp-messages/bp-messages-loader.php
index 4d8682b200faf69adb4352923f97002caae82652..d7c652d0cb98ee85bdf80eb23b9f2146934b292d 100644
--- a/wp-content/plugins/buddypress/bp-messages/bp-messages-loader.php
+++ b/wp-content/plugins/buddypress/bp-messages/bp-messages-loader.php
@@ -27,11 +27,14 @@ class BP_Messages_Component extends BP_Component {
 	 *
 	 * @since BuddyPress (1.5)
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'messages',
 			__( 'Private Messages', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 50
+			)
 		);
 	}
 
@@ -39,6 +42,7 @@ class BP_Messages_Component extends BP_Component {
 	 * Include files
 	 */
 	public function includes( $includes = array() ) {
+
 		// Files to include
 		$includes = array(
 			'cssjs',
@@ -49,7 +53,8 @@ class BP_Messages_Component extends BP_Component {
 			'filters',
 			'template',
 			'functions',
-			'notifications'
+			'notifications',
+			'widgets',
 		);
 
 		parent::includes( $includes );
@@ -62,10 +67,9 @@ class BP_Messages_Component extends BP_Component {
 	 * backwards compatibility.
 	 *
 	 * @since BuddyPress (1.5)
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_globals( $args = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		// Define a slug, if necessary
 		if ( !defined( 'BP_MESSAGES_SLUG' ) )
@@ -95,17 +99,21 @@ class BP_Messages_Component extends BP_Component {
 
 	/**
 	 * Setup BuddyBar navigation
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
 
-		$sub_nav = array();
-		$name    = sprintf( __( 'Messages <span>%s</span>', 'buddypress' ), bp_get_total_unread_messages_count() );
+		// Only grab count if we're on a user page and current user has access
+		if ( bp_is_user() && bp_user_has_access() ) {
+			$count    = bp_get_total_unread_messages_count();
+			$class    = ( 0 === $count ) ? 'no-count' : 'count';
+			$nav_name = sprintf( __( 'Messages <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), number_format_i18n( $count ) );
+		} else {
+			$nav_name = __( 'Messages', 'buddypress' );
+		}
 
 		// Add 'Messages' to the main navigation
 		$main_nav = array(
-			'name'                    => $name,
+			'name'                    => $nav_name,
 			'slug'                    => $this->slug,
 			'position'                => 50,
 			'show_for_displayed_user' => false,
@@ -174,14 +182,9 @@ class BP_Messages_Component extends BP_Component {
 
 	/**
 	 * Set up the Toolbar
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_admin_bar( $wp_admin_nav = array() ) {
-		global $bp;
-
-		// Prevent debug notices
-		$wp_admin_nav = array();
+		$bp = buddypress();
 
 		// Menus for logged in user
 		if ( is_user_logged_in() ) {
@@ -248,11 +251,9 @@ class BP_Messages_Component extends BP_Component {
 
 	/**
 	 * Sets up the title for pages and <title>
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
-	function setup_title() {
-		global $bp;
+	public function setup_title() {
+		$bp = buddypress();
 
 		if ( bp_is_messages_component() ) {
 			if ( bp_is_my_profile() ) {
@@ -272,7 +273,6 @@ class BP_Messages_Component extends BP_Component {
 }
 
 function bp_setup_messages() {
-	global $bp;
-	$bp->messages = new BP_Messages_Component();
+	buddypress()->messages = new BP_Messages_Component();
 }
 add_action( 'bp_setup_components', 'bp_setup_messages', 6 );
diff --git a/wp-content/plugins/buddypress/bp-messages/bp-messages-notifications.php b/wp-content/plugins/buddypress/bp-messages/bp-messages-notifications.php
index a55d0d1b7fa805081df29147122cc0cdec1e72fb..f50ed30e10eadf9f50cdedcc78db36fe70f79fbc 100644
--- a/wp-content/plugins/buddypress/bp-messages/bp-messages-notifications.php
+++ b/wp-content/plugins/buddypress/bp-messages/bp-messages-notifications.php
@@ -7,34 +7,53 @@
  * @subpackage MessagesNotifications
  */
 
-
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
-function messages_notification_new_message( $args = array() ) {
+/** Email *********************************************************************/
+
+/**
+ * Email message recipients to alert them of a new unread private message
+ *
+ * @since BuddyPress (1.0)
+ * @param array $raw_args
+ */
+function messages_notification_new_message( $raw_args = array() ) {
+
+	// Cast possible $message object as an array
+	if ( is_object( $raw_args ) ) {
+		$args = (array) $raw_args;
+	} else {
+		$args = $raw_args;
+	}
 
 	// These should be extracted below
 	$recipients    = array();
 	$email_subject = $email_content = '';
+	$sender_id     = 0;
 
+	// Barf
 	extract( $args );
 
+	// Get the sender display name
 	$sender_name = bp_core_get_user_displayname( $sender_id );
 
 	// Bail if no recipients
 	if ( ! empty( $recipients ) ) {
 
-		foreach( $recipients as $recipient ) {
+		foreach ( $recipients as $recipient ) {
 
-			if ( $sender_id == $recipient->user_id || 'no' == bp_get_user_meta( $recipient->user_id, 'notification_messages_new_message', true ) )
+			if ( $sender_id == $recipient->user_id || 'no' == bp_get_user_meta( $recipient->user_id, 'notification_messages_new_message', true ) ) {
 				continue;
+			}
 
 			// User data and links
-			$ud            = get_userdata( $recipient->user_id );
+			$ud = get_userdata( $recipient->user_id );
 
 			// Bail if user cannot be found
-			if ( empty( $ud ) )
+			if ( empty( $ud ) ) {
 				continue;
+			}
 
 			$message_link  = bp_core_get_user_domain( $recipient->user_id ) . bp_get_messages_slug() .'/';
 			$settings_slug = function_exists( 'bp_get_settings_slug' ) ? bp_get_settings_slug() : 'settings';
@@ -43,7 +62,7 @@ function messages_notification_new_message( $args = array() ) {
 			// Sender info
 			$sender_name   = stripslashes( $sender_name );
 			$subject       = stripslashes( wp_filter_kses( $subject ) );
-			$content       = stripslashes( wp_filter_kses( $content ) );
+			$content       = stripslashes( wp_filter_kses( $message ) );
 
 			// Set up and send the message
 			$email_to      = $ud->user_email;
@@ -77,3 +96,126 @@ To view and read your messages please log in and visit: %4$s
 
 	do_action( 'bp_messages_sent_notification_email', $recipients, $email_subject, $email_content, $args );
 }
+add_action( 'messages_message_sent', 'messages_notification_new_message', 10 );
+
+/** Notifications *************************************************************/
+
+/**
+ * Format the BuddyBar/Toolbar notifications for the Messages component
+ *
+ * @since BuddyPress (1.0)
+ * @param string $action The kind of notification being rendered
+ * @param int $item_id The primary item id
+ * @param int $secondary_item_id The secondary item id
+ * @param int $total_items The total number of messaging-related notifications waiting for the user
+ * @param string $format 'string' for BuddyBar-compatible notifications; 'array' for WP Toolbar
+ */
+function messages_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
+
+	if ( 'new_message' === $action ) {
+		$link  = trailingslashit( bp_loggedin_user_domain() . bp_get_messages_slug() . '/inbox' );
+		$title = __( 'Inbox', 'buddypress' );
+
+		if ( (int) $total_items > 1 ) {
+			$text   = sprintf( __('You have %d new messages', 'buddypress' ), (int) $total_items );
+			$filter = 'bp_messages_multiple_new_message_notification';
+		} else {
+			// get message thread ID
+			$message   = new BP_Messages_Message( $item_id );
+			$thread_id = $message->thread_id;
+
+			$link = bp_get_message_thread_view_link( $thread_id );
+
+			if ( ! empty( $secondary_item_id ) ) {
+				$text = sprintf( __( '%s sent you a new private message', 'buddypress' ), bp_core_get_user_displayname( $secondary_item_id ) );
+			} else {
+				$text = sprintf( __( 'You have %d new private messages', 'buddypress' ), (int) $total_items );
+			}
+			$filter = 'bp_messages_single_new_message_notification';
+		}
+	}
+
+	if ( 'string' === $format ) {
+		$return = apply_filters( $filter, '<a href="' . esc_url( $link ) . '" title="' . esc_attr( $title ) . '">' . esc_html( $text ) . '</a>', (int) $total_items, $text, $link, $item_id, $secondary_item_id );
+	} else {
+		$return = apply_filters( $filter, array(
+			'text' => $text,
+			'link' => $link
+		), $link, (int) $total_items, $text, $link, $item_id, $secondary_item_id );
+	}
+
+	do_action( 'messages_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
+
+	return $return;
+}
+
+/**
+ * Send notifications to message recipients
+ *
+ * @since BuddyPress (1.9.0)
+ * @param obj $message
+ */
+function bp_messages_message_sent_add_notification( $message ) {
+	if ( bp_is_active( 'notifications' ) && ! empty( $message->recipients ) ) {
+		foreach ( (array) $message->recipients as $recipient ) {
+			bp_notifications_add_notification( array(
+				'user_id'           => $recipient->user_id,
+				'item_id'           => $message->id,
+				'secondary_item_id' => $message->sender_id,
+				'component_name'    => buddypress()->messages->id,
+				'component_action'  => 'new_message',
+				'date_notified'     => bp_core_current_time(),
+				'is_new'            => 1,
+			) );
+		}
+	}
+}
+add_action( 'messages_message_sent', 'bp_messages_message_sent_add_notification', 10 );
+
+/**
+ * Mark new message notification when member reads a message thread directly.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_messages_screen_conversation_mark_notifications() {
+	if ( bp_is_active( 'notifications' ) ) {
+		global $thread_template;
+
+		// get unread PM notifications for the user
+		$new_pm_notifications = BP_Notifications_Notification::get( array(
+			'user_id'           => bp_loggedin_user_id(),
+			'component_name'    => buddypress()->messages->id,
+			'component_action'  => 'new_message',
+			'is_new'            => 1,
+		) );
+		$unread_message_ids = wp_list_pluck( $new_pm_notifications, 'item_id' );
+
+		// no unread PMs, so stop!
+		if ( empty( $unread_message_ids ) ) {
+			return;
+		}
+
+		// get the unread message ids for this thread only
+		$message_ids = array_intersect( $unread_message_ids, wp_list_pluck( $thread_template->thread->messages, 'id' ) );
+
+		// mark each notification for each PM message as read
+		foreach ( $message_ids as $message_id ) {
+			bp_notifications_mark_notifications_by_item_id( bp_loggedin_user_id(), (int) $message_id, buddypress()->messages->id, 'new_message' );
+		}
+	}
+}
+add_action( 'thread_loop_start', 'bp_messages_screen_conversation_mark_notifications', 10 );
+
+/**
+ * When a message is deleted, delete corresponding notifications.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $message_id ID of the message.
+ */
+function bp_messages_message_delete_notifications( $message_id = 0 ) {
+	if ( bp_is_active( 'notifications' ) && ! empty( $message_id ) ) {
+		bp_notifications_delete_notifications_by_item_id( bp_loggedin_user_id(), (int) $message_id, buddypress()->messages->id, 'new_message' );
+	}
+}
+add_action( 'messages_thread_deleted_thread', 'bp_messages_message_delete_notifications', 10, 1 );
diff --git a/wp-content/plugins/buddypress/bp-messages/bp-messages-template.php b/wp-content/plugins/buddypress/bp-messages/bp-messages-template.php
index 3c9d9108cd376c5634157fd9c8b14d2e54441e88..07729852fbd885731680e1e14c9989ae0dbcbc87 100644
--- a/wp-content/plugins/buddypress/bp-messages/bp-messages-template.php
+++ b/wp-content/plugins/buddypress/bp-messages/bp-messages-template.php
@@ -165,41 +165,59 @@ class BP_Messages_Box_Template {
 	}
 }
 
+/**
+ * Retrieve private message threads for display in inbox/sentbox/notices
+ *
+ * Similar to WordPress's have_posts() function, this function is responsible
+ * for querying the database and retrieving private messages for display inside
+ * the theme via individual template parts for a member's inbox/sentbox/notices.
+ *
+ * @since BuddyPress (1.0.0)
+ *
+ * @global BP_Messages_Box_Template $messages_template
+ * @param array $args
+ * @return object
+ */
 function bp_has_message_threads( $args = '' ) {
-	global $bp, $messages_template;
+	global $messages_template;
 
-	$defaults = array(
+	// The default box the user is looking at
+	if ( bp_is_current_action( 'sentbox' ) ) {
+		$default_box = 'sentbox';
+	} elseif ( bp_is_current_action( 'notices' ) ) {
+		$default_box = 'notices';
+	} else {
+		$default_box = 'inbox';
+	}
+
+	// Parse the arguments
+	$r = bp_parse_args( $args, array(
 		'user_id'      => bp_loggedin_user_id(),
-		'box'          => 'inbox',
+		'box'          => $default_box,
 		'per_page'     => 10,
 		'max'          => false,
 		'type'         => 'all',
 		'search_terms' => isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '',
 		'page_arg'     => 'mpage', // See https://buddypress.trac.wordpress.org/ticket/3679
-	);
-
-	$r = wp_parse_args( $args, $defaults );
-	extract( $r, EXTR_SKIP );
+	), 'has_message_threads' );
 
+	// If trying to access notices without capabilities, redirect to root domain
 	if ( bp_is_current_action( 'notices' ) && !bp_current_user_can( 'bp_moderate' ) ) {
-		wp_redirect( bp_displayed_user_id() );
-	} else {
-		if ( bp_is_current_action( 'inbox' ) ) {
-			bp_core_delete_notifications_by_type( bp_loggedin_user_id(), $bp->messages->id, 'new_message' );
-		}
-
-		if ( bp_is_current_action( 'sentbox' ) ) {
-			$box = 'sentbox';
-		}
-
-		if ( bp_is_current_action( 'notices' ) ) {
-			$box = 'notices';
-		}
-
-		$messages_template = new BP_Messages_Box_Template( $user_id, $box, $per_page, $max, $type, $search_terms, $page_arg );
+		bp_core_redirect( bp_displayed_user_domain() );
 	}
 
-	return apply_filters( 'bp_has_message_threads', $messages_template->has_threads(), $messages_template );
+	// Load the messages loop global up with messages
+	$messages_template = new BP_Messages_Box_Template(
+		$r['user_id'],
+		$r['box'],
+		$r['per_page'],
+		$r['max'],
+		$r['type'],
+		$r['search_terms'],
+		$r['page_arg']
+	);
+
+	return apply_filters( 'bp_has_message_threads', $messages_template->has_threads(), $messages_template, $r );
 }
 
 function bp_message_threads() {
@@ -239,6 +257,38 @@ function bp_message_thread_excerpt() {
 		return apply_filters( 'bp_get_message_thread_excerpt', strip_tags( bp_create_excerpt( $messages_template->thread->last_message_content, 75 ) ) );
 	}
 
+/**
+ * Output the thread's last message content
+ *
+ * When viewing your Inbox, the last message is the most recent message in
+ * the thread of which you are *not* the author.
+ *
+ * When viewing your Sentbox, last message is the most recent message in
+ * the thread of which you *are* the member.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_message_thread_content() {
+	echo bp_get_message_thread_content();
+}
+	/**
+	 * Return the thread's last message content
+	 *
+	 * When viewing your Inbox, the last message is the most recent message in
+	 * the thread of which you are *not* the author.
+	 *
+	 * When viewing your Sentbox, last message is the most recent message in
+	 * the thread of which you *are* the member.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 * @return string The raw content of the last message in the thread
+	 */
+	function bp_get_message_thread_content() {
+		global $messages_template;
+
+		return apply_filters( 'bp_get_message_thread_content', $messages_template->thread->last_message_content );
+	}
+
 function bp_message_thread_from() {
 	echo bp_get_message_thread_from();
 }
@@ -256,12 +306,19 @@ function bp_message_thread_to() {
 		return apply_filters( 'bp_message_thread_to', BP_Messages_Thread::get_recipient_links($messages_template->thread->recipients ) );
 	}
 
-function bp_message_thread_view_link() {
-	echo bp_get_message_thread_view_link();
+function bp_message_thread_view_link( $thread_id = 0 ) {
+	echo bp_get_message_thread_view_link( $thread_id );
 }
-	function bp_get_message_thread_view_link() {
-		global $messages_template, $bp;
-		return apply_filters( 'bp_get_message_thread_view_link', trailingslashit( bp_loggedin_user_domain() . $bp->messages->slug . '/view/' . $messages_template->thread->thread_id ) );
+	function bp_get_message_thread_view_link( $thread_id = 0 ) {
+		global $messages_template;
+
+		if ( empty( $messages_template ) && (int) $thread_id > 0 ) {
+			$thread_id = (int) $thread_id;
+		} else {
+			$thread_id = $messages_template->thread->thread_id;
+		}
+
+		return apply_filters( 'bp_get_message_thread_view_link', trailingslashit( bp_loggedin_user_domain() . buddypress()->messages->slug . '/view/' . $thread_id ) );
 	}
 
 function bp_message_thread_delete_link() {
@@ -317,13 +374,60 @@ function bp_message_thread_last_post_date() {
 		return apply_filters( 'bp_get_message_thread_last_post_date', bp_format_time( strtotime( $messages_template->thread->last_message_date ) ) );
 	}
 
-function bp_message_thread_avatar() {
-	echo bp_get_message_thread_avatar();
+/**
+ * Output the avatar for the last sender in the current message thread.
+ *
+ * @see bp_get_message_thread_avatar() for a description of arguments.
+ *
+ * @param array $args See {@link bp_get_message_thread_avatar()}.
+ */
+function bp_message_thread_avatar( $args = '' ) {
+	echo bp_get_message_thread_avatar( $args );
 }
-	function bp_get_message_thread_avatar() {
+	/**
+	 * Return the avatar for the last sender in the current message thread.
+	 *
+	 * @see bp_core_fetch_avatar() For a description of arguments and
+	 *      return values.
+	 *
+	 * @param array $args {
+	 *     Arguments are listed here with an explanation of their defaults.
+	 *     For more information about the arguments, see
+	 *     {@link bp_core_fetch_avatar()}.
+	 *     @type string $type Default: 'thumb'.
+	 *     @type int|bool $width Default: false.
+	 *     @type int|bool $height Default: false.
+	 *     @type string $class Default: 'avatar'.
+	 *     @type string|bool $id Default: false.
+	 *     @type string $alt Default: 'Profile picture of [display name]'.
+	 * }
+	 * @return User avatar string.
+	 */
+	function bp_get_message_thread_avatar( $args = '' ) {
 		global $messages_template;
 
-		return apply_filters( 'bp_get_message_thread_avatar', bp_core_fetch_avatar( array( 'item_id' => $messages_template->thread->last_sender_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $messages_template->thread->last_sender_id ) ) ) ) );
+		$fullname = bp_core_get_user_displayname( $messages_template->thread->last_sender_id );
+
+		$defaults = array(
+			'type'   => 'thumb',
+			'width'  => false,
+			'height' => false,
+			'class'  => 'avatar',
+			'id'     => false,
+			'alt'    => sprintf( __( 'Profile picture of %s', 'buddypress' ), $fullname )
+		);
+
+		$r = wp_parse_args( $args, $defaults );
+
+		return apply_filters( 'bp_get_message_thread_avatar', bp_core_fetch_avatar( array(
+			'item_id' => $messages_template->thread->last_sender_id,
+			'type'    => $r['type'],
+			'alt'     => $r['alt'],
+			'css_id'  => $r['id'],
+			'class'   => $r['class'],
+			'width'   => $r['width'],
+			'height'  => $r['height'],
+		) ) );
 	}
 
 function bp_total_unread_messages_count() {
@@ -349,7 +453,7 @@ function bp_messages_pagination_count() {
 	$to_num = bp_core_number_format( ( $start_num + ( $messages_template->pag_num - 1 ) > $messages_template->total_thread_count ) ? $messages_template->total_thread_count : $start_num + ( $messages_template->pag_num - 1 ) );
 	$total = bp_core_number_format( $messages_template->total_thread_count );
 
-	echo sprintf( __( 'Viewing message %1$s to %2$s (of %3$s messages)', 'buddypress' ), $from_num, $to_num, $total ); ?><?php
+	echo sprintf( _n( 'Viewing message %1$s to %2$s (of %3$s message)', 'Viewing message %1$s to %2$s (of %3$s messages)', $total, 'buddypress' ), $from_num, $to_num, number_format_i18n( $total ) ); ?><?php
 }
 
 /**
@@ -364,7 +468,7 @@ function bp_message_search_form() {
 
 	<form action="" method="get" id="search-message-form">
 		<label><input type="text" name="s" id="messages_search" <?php if ( $search_value === $default_search_value ) : ?>placeholder="<?php echo esc_html( $search_value ); ?>"<?php endif; ?> <?php if ( $search_value !== $default_search_value ) : ?>value="<?php echo esc_html( $search_value ); ?>"<?php endif; ?> /></label>
-		<input type="submit" id="messages_search_submit" name="messages_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
+		<input type="submit" id="messages_search_submit" name="messages_search_submit" value="<?php esc_attr_e( 'Search', 'buddypress' ) ?>" />
 	</form>
 
 <?php
@@ -585,14 +689,12 @@ function bp_messages_slug() {
 	}
 
 function bp_message_get_notices() {
-	global $userdata;
-
 	$notice = BP_Messages_Notice::get_active();
 
 	if ( empty( $notice ) )
 		return false;
 
-	$closed_notices = bp_get_user_meta( $userdata->ID, 'closed_notices', true );
+	$closed_notices = bp_get_user_meta( bp_loggedin_user_id(), 'closed_notices', true );
 
 	if ( !$closed_notices )
 		$closed_notices = array();
@@ -850,6 +952,27 @@ function bp_the_thread_recipients() {
 		return apply_filters( 'bp_get_the_thread_recipients', implode( ', ', $recipient_links ) );
 	}
 
+/**
+ * Echoes the ID of the current message in the thread
+ *
+ * @since BuddyPress (1.9)
+ */
+function bp_the_thread_message_id() {
+	echo bp_get_the_thread_message_id();
+}
+	/**
+	 * Gets the ID of the current message in the thread
+	 *
+	 * @since BuddyPress (1.9)
+	 * @return int
+	 */
+	function bp_get_the_thread_message_id() {
+		global $thread_template;
+
+		$thread_message_id = isset( $thread_template->message->id ) ? (int) $thread_template->message->id : null;
+		return apply_filters( 'bp_get_the_thread_message_id', $thread_message_id );
+	}
+
 function bp_the_thread_message_alt_class() {
 	echo bp_get_the_thread_message_alt_class();
 }
diff --git a/wp-content/plugins/buddypress/bp-messages/bp-messages-widgets.php b/wp-content/plugins/buddypress/bp-messages/bp-messages-widgets.php
new file mode 100644
index 0000000000000000000000000000000000000000..aa26a33e202b5723f013b6be53176b2785f409bb
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-messages/bp-messages-widgets.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * BuddyPress Messages Widgets
+ *
+ * @package BuddyPress
+ * @subpackage Messages
+ */
+
+/**
+ * Register widgets for the Messages component.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_messages_register_widgets() {
+	add_action( 'widgets_init', create_function('', 'return register_widget( "BP_Messages_Sitewide_Notices_Widget" );') );
+}
+add_action( 'bp_register_widgets', 'bp_messages_register_widgets' );
+
+/** Sitewide Notices widget *************************************************/
+
+/**
+ * A widget that displays sitewide notices.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+class BP_Messages_Sitewide_Notices_Widget extends WP_Widget {
+
+	/**
+	 * Constructor method
+	 */
+	function __construct() {
+		parent::__construct(
+			'bp_messages_sitewide_notices_widget',
+			__( '(BuddyPress) Sitewide Notices', 'buddypress' ),
+			array(
+				'classname'   => 'widget_bp_core_sitewide_messages buddypress widget',
+				'description' => __( 'Display Sitewide Notices posted by the site administrator', 'buddypress' ),
+			)
+		);
+	}
+
+	/**
+	 * Render the widget.
+	 *
+	 * @see WP_Widget::widget() for a description of parameters.
+	 *
+	 * @param array $args See {@WP_Widget::widget()}.
+	 * @param array $args See {@WP_Widget::widget()}.
+	 */
+	public function widget( $args, $instance ) {
+
+		if ( ! is_user_logged_in() ) {
+			return;
+		}
+
+		// Don't display the widget if there are no Notices to show
+		$notices = BP_Messages_Notice::get_active();
+		if ( empty( $notices ) ) {
+			return;
+		}
+
+		extract( $args );
+
+		$title = ! empty( $instance['title'] ) ? $instance['title'] : '';
+		$title = apply_filters( 'widget_title', $title, $instance );
+
+		echo $before_widget;
+		echo $before_title . $title . $after_title; ?>
+
+		<div class="bp-site-wide-message">
+			<?php bp_message_get_notices(); ?>
+		</div>
+
+		<?php
+
+		echo $after_widget;
+	}
+
+	/**
+	 * Process the saved settings for the widget.
+	 *
+	 * @see WP_Widget::update() for a description of parameters and
+	 *      return values.
+	 *
+	 * @param array $new_instance See {@WP_Widget::update()}.
+	 * @param array $old_instance See {@WP_Widget::update()}.
+	 * @return array $instance See {@WP_Widget::update()}.
+	 */
+	public function update( $new_instance, $old_instance ) {
+		$instance = $old_instance;
+		$instance['title'] = strip_tags( $new_instance['title'] );
+		return $instance;
+	}
+
+	/**
+	 * Render the settings form for Appearance > Widgets.
+	 *
+	 * @see WP_Widget::form() for a description of parameters.
+	 *
+	 * @param array $instance See {@WP_Widget::form()}.
+	 */
+	public function form( $instance ) {
+		$instance = wp_parse_args( (array) $instance, array(
+			'title' => '',
+		) );
+
+		$title = strip_tags( $instance['title'] ); ?>
+
+		<p>
+			<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'buddypress' ); ?></label>
+			<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
+		</p>
+
+		<?php
+	}
+}
diff --git a/wp-content/plugins/buddypress/bp-messages/css/autocomplete/jquery.autocompletefb.min.css b/wp-content/plugins/buddypress/bp-messages/css/autocomplete/jquery.autocompletefb.min.css
index 77388d0dd9051c6987c0699d321aababc5fdc746..5c4f759d0e201c530109765202a3421ead7fdcec 100644
--- a/wp-content/plugins/buddypress/bp-messages/css/autocomplete/jquery.autocompletefb.min.css
+++ b/wp-content/plugins/buddypress/bp-messages/css/autocomplete/jquery.autocompletefb.min.css
@@ -1 +1 @@
-.ac_results{padding:0;overflow:hidden;z-index:99999;background:#fff;border:1px solid #ccc;-moz-border-radius-bottomleft:3px;-khtml-border-bottom-left-radius:3px;-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-moz-border-radius-bottomright:3px;-khtml-border-bottom-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px}.ac_results ul{width:100%;list-style-position:outside;list-style:none;padding:0;margin:0}.ac_results li{margin:0;padding:5px 10px;cursor:pointer;display:block;font-size:1em;line-height:16px;overflow:hidden}.ac_results li img{margin-right:5px}.ac_loading{background:url('../../../bp-themes/bp-default/_inc/images/ajax-loader.gif') right center no-repeat}.ac_odd{background-color:#f0f0f0}.ac_over{background-color:#888;color:#fff}ul.acfb-holder{margin:0;height:auto!important;height:1%;overflow:hidden;padding:0;list-style:none}ul.acfb-holder li{float:left;margin:0 5px 4px 0;list-style-type:none}ul.acfb-holder li.friend-tab{border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;border:1px solid #ffe7c7;padding:2px 7px 2px;background:#fff9df;font-size:1em}li.friend-tab img.avatar{border-width:2px!important;vertical-align:middle}li.friend-tab span.p{padding-left:5px;font-size:.8em;cursor:pointer}input#send-to-input{width:275px}
\ No newline at end of file
+.ac_results{padding:0;overflow:hidden;z-index:99999;background:#fff;border:1px solid #ccc;-moz-border-radius-bottomleft:3px;-khtml-border-bottom-left-radius:3px;-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-moz-border-radius-bottomright:3px;-khtml-border-bottom-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px}.ac_results ul{width:100%;list-style-position:outside;list-style:none;padding:0;margin:0}.ac_results li{margin:0;padding:5px 10px;cursor:pointer;display:block;font-size:1em;line-height:16px;overflow:hidden}.ac_results li img{margin-right:5px}.ac_loading{background:url('../../../bp-themes/bp-default/_inc/images/ajax-loader.gif') right center no-repeat}.ac_odd{background-color:#f0f0f0}.ac_over{background-color:#888;color:#fff}ul.acfb-holder{margin:0;height:auto !important;height:1%;overflow:hidden;padding:0;list-style:none}ul.acfb-holder li{float:left;margin:0 5px 4px 0;list-style-type:none}ul.acfb-holder li.friend-tab{border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;border:1px solid #ffe7c7;padding:2px 7px 2px;background:#fff9df;font-size:1em}li.friend-tab img.avatar{border-width:2px !important;vertical-align:middle}li.friend-tab span.p{padding-left:5px;font-size:.8em;cursor:pointer}input#send-to-input{width:275px}
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-messages/js/autocomplete/jquery.autocomplete.min.js b/wp-content/plugins/buddypress/bp-messages/js/autocomplete/jquery.autocomplete.min.js
index 42a07995ae8953717263bfb4c2c4999492b4ac06..811fd97ee5b3aa42308c9e6b2a191be0370e55b3 100644
--- a/wp-content/plugins/buddypress/bp-messages/js/autocomplete/jquery.autocomplete.min.js
+++ b/wp-content/plugins/buddypress/bp-messages/js/autocomplete/jquery.autocomplete.min.js
@@ -10,4 +10,4 @@
  * Revision: $Id: jquery.autocomplete.js 4485 2008-01-20 13:52:47Z joern.zaefferer $
  *
  */
-(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var w={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,w);b.keydown(function(x){u=x.keyCode;switch(x.keyCode){case c.UP:x.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:x.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:x.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:x.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){if(!g.multiple){b.blur()}x.preventDefault();b.focus()}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).keypress(function(){}).focus(function(){e++}).blur(function(){e=0;if(!w.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var x=(arguments.length>1)?arguments[1]:null;function y(C,B){var z;if(B&&B.length){for(var A=0;A<B.length;A++){if(B[A].result.toLowerCase()==C.toLowerCase()){z=B[A];break}}}if(typeof x=="function"){x(z)}else{b.trigger("result",z&&[z.data,z.value])}}a.each(h(b.val()),function(z,A){f(A,y,y)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind()});function d(){var y=r.selected();if(!y){return false}var x=y.result;p=x;if(g.multiple){var z=h(b.val());if(z.length>1){x=z.slice(0,z.length-1).join(g.multipleSeparator)+g.multipleSeparator+x}x+=g.multipleSeparator}b.val(x);v();b.trigger("result",[y.data,y.value]);return true}function t(z,y){if(u==c.DEL){r.hide();return}var x=b.val();if(!y&&x==p){return}p=x;x=i(x);if(x.length>=g.minChars){b.addClass(g.loadingClass);jQuery("#send-to-input").addClass("loading");if(!g.matchCase){x=x.toLowerCase()}f(x,k,v)}else{n();r.hide()}}function h(y){if(!y){return[""]}var z=y.split(a.trim(g.multipleSeparator));var x=[];a.each(z,function(A,B){if(a.trim(B)){x[A]=a.trim(B)}});return x}function i(x){if(!g.multiple){return x}var y=h(x);return y[y.length-1]}function q(x,y){if(g.autoFill&&(i(b.val()).toLowerCase()==x.toLowerCase())&&u!=8){b.val(b.val()+y.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+y.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(x){if(!x){b.val("")}})}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);var x=y[0].value.split(";");y.value=x[0];q(z,y.value);r.show()}else{v()}}function f(y,A,x){if(!g.matchCase){y=y.toLowerCase()}var z=m.load(y);if(z&&z.length){A(y,z)}else{if((typeof g.url=="string")&&(g.url.length>0)){var B={};a.each(g.extraParams,function(C,D){B[C]=typeof D=="function"?D():D});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(y),limit:g.max,action:"messages_autocomplete_results",cookie:encodeURIComponent(document.cookie)},B),success:function(D){var C=g.parse&&g.parse(D)||o(D);m.add(y,C);A(y,C)}})}else{x(y)}}}function o(A){var x=[];var z=A.split("\n");for(var y=0;y<z.length;y++){var B=a.trim(z[y]);if(B){B=B.split("|");x[x.length]={data:B,value:B[0],result:g.formatResult&&g.formatResult(B,B[0])||B[0]}}}return x}function n(){b.removeClass(g.loadingClass);jQuery("#send-to-input").removeClass("loading")}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:250,attachTo:"body"};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatItem(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(e.attachTo);o=a("<ul>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass();g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li>").html(e.highlight(w,m)).addClass(v%2==0?"ac_event":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}o.bgiframe()}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);
\ No newline at end of file
+;(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var w={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,w);b.keydown(function(x){u=x.keyCode;switch(x.keyCode){case c.UP:x.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:x.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:x.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:x.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){if(!g.multiple){b.blur()}x.preventDefault();b.focus()}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).keypress(function(){}).focus(function(){e++}).blur(function(){e=0;if(!w.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var x=(arguments.length>1)?arguments[1]:null;function y(C,B){var z;if(B&&B.length){for(var A=0;A<B.length;A++){if(B[A].result.toLowerCase()==C.toLowerCase()){z=B[A];break}}}if(typeof x=="function"){x(z)}else{b.trigger("result",z&&[z.data,z.value])}}a.each(h(b.val()),function(z,A){f(A,y,y)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind()});function d(){var y=r.selected();if(!y){return false}var x=y.result;p=x;if(g.multiple){var z=h(b.val());if(z.length>1){x=z.slice(0,z.length-1).join(g.multipleSeparator)+g.multipleSeparator+x}x+=g.multipleSeparator}b.val(x);v();b.trigger("result",[y.data,y.value]);return true}function t(z,y){if(u==c.DEL){r.hide();return}var x=b.val();if(!y&&x==p){return}p=x;x=i(x);if(x.length>=g.minChars){b.addClass(g.loadingClass);jQuery("#send-to-input").addClass("loading");if(!g.matchCase){x=x.toLowerCase()}f(x,k,v)}else{n();r.hide()}}function h(y){if(!y){return[""]}var z=y.split(a.trim(g.multipleSeparator));var x=[];a.each(z,function(A,B){if(a.trim(B)){x[A]=a.trim(B)}});return x}function i(x){if(!g.multiple){return x}var y=h(x);return y[y.length-1]}function q(x,y){if(g.autoFill&&(i(b.val()).toLowerCase()==x.toLowerCase())&&u!=8){b.val(b.val()+y.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+y.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(x){if(!x){b.val("")}})}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);var x=y[0].value.split(";");y.value=x[0];q(z,y.value);r.show()}else{v()}}function f(y,A,x){if(!g.matchCase){y=y.toLowerCase()}var z=m.load(y);if(z&&z.length){A(y,z)}else{if((typeof g.url=="string")&&(g.url.length>0)){var B={};a.each(g.extraParams,function(C,D){B[C]=typeof D=="function"?D():D});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(y),limit:g.max,action:"messages_autocomplete_results",cookie:encodeURIComponent(document.cookie)},B),success:function(D){var C=g.parse&&g.parse(D)||o(D);m.add(y,C);A(y,C)}})}else{x(y)}}}function o(A){var x=[];var z=A.split("\n");for(var y=0;y<z.length;y++){var B=a.trim(z[y]);if(B){B=B.split("|");x[x.length]={data:B,value:B[0],result:g.formatResult&&g.formatResult(B,B[0])||B[0]}}}return x}function n(){b.removeClass(g.loadingClass);jQuery("#send-to-input").removeClass("loading")}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:250,attachTo:"body"};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatItem(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(e.attachTo);o=a("<ul>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass();g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li>").html(e.highlight(w,m)).addClass(v%2==0?"ac_event":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}o.bgiframe()}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-messages/js/autocomplete/jquery.autocompletefb.min.js b/wp-content/plugins/buddypress/bp-messages/js/autocomplete/jquery.autocompletefb.min.js
index ba1fb2ec77f51f8cd055527f410bb28f40682760..539ff4afd567c8ea756b10ab0b9941fee534b6db 100644
--- a/wp-content/plugins/buddypress/bp-messages/js/autocomplete/jquery.autocompletefb.min.js
+++ b/wp-content/plugins/buddypress/bp-messages/js/autocomplete/jquery.autocompletefb.min.js
@@ -13,4 +13,4 @@
  *   http://www.opensource.org/licenses/mit-license.php
  *   http://www.gnu.org/licenses/gpl.html
  */
-jQuery.fn.autoCompletefb=function(b){var c=this;var d={ul:c,urlLookup:[""],acOptions:{},foundClass:".friend-tab",inputClass:".send-to-input"};if(b){jQuery.extend(d,b)}var a={params:d,removeFind:function(e){a.removeUsername(e);jQuery(e).unbind("click").parent().remove();jQuery(d.inputClass,c).focus();return c.acfb},removeUsername:function(f){var e=f.parentNode.id.substr(f.parentNode.id.indexOf("-")+1);jQuery("#send-to-usernames").removeClass(e)}};jQuery(d.foundClass+" img.p").click(function(){a.removeFind(this)});jQuery(d.inputClass,c).autocomplete(d.urlLookup,d.acOptions);jQuery(d.inputClass,c).result(function(n,o,m){var m=d.foundClass.replace(/\./,"");var o=String(o).split(" (");var j=o[1].substr(0,o[1].length-1);if(0===jQuery(d.inputClass).siblings("#un-"+j).length){var k="#link-"+j;var h=jQuery(k).attr("href");var i='<li class="'+m+'" id="un-'+j+'"><span><a href="'+h+'">'+o[0]+'</a></span> <span class="p">X</span></li>';var g=jQuery(d.inputClass,c).before(i);jQuery("#send-to-usernames").addClass(j);jQuery(".p",g[0].previousSibling).click(function(){a.removeFind(this)})}jQuery(d.inputClass,c).val("")});jQuery(d.inputClass,c).focus();return a};
\ No newline at end of file
+;jQuery.fn.autoCompletefb=function(b){var c=this;var d={ul:c,urlLookup:[""],acOptions:{},foundClass:".friend-tab",inputClass:".send-to-input"};if(b){jQuery.extend(d,b)}var a={params:d,removeFind:function(e){a.removeUsername(e);jQuery(e).unbind("click").parent().remove();jQuery(d.inputClass,c).focus();return c.acfb},removeUsername:function(f){var e=f.parentNode.id.substr(f.parentNode.id.indexOf("-")+1);jQuery("#send-to-usernames").removeClass(e)}};jQuery(d.foundClass+" img.p").click(function(){a.removeFind(this)});jQuery(d.inputClass,c).autocomplete(d.urlLookup,d.acOptions);jQuery(d.inputClass,c).result(function(n,o,m){var m=d.foundClass.replace(/\./,"");var o=String(o).split(" (");var j=o[1].substr(0,o[1].length-1);if(0===jQuery(d.inputClass).siblings("#un-"+j).length){var k="#link-"+j;var h=jQuery(k).attr("href");var i='<li class="'+m+'" id="un-'+j+'"><span><a href="'+h+'">'+o[0]+'</a></span> <span class="p">X</span></li>';var g=jQuery(d.inputClass,c).before(i);jQuery("#send-to-usernames").addClass(j);jQuery(".p",g[0].previousSibling).click(function(){a.removeFind(this)})}jQuery(d.inputClass,c).val("")});jQuery(d.inputClass,c).focus();return a};
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-actions.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-actions.php
new file mode 100644
index 0000000000000000000000000000000000000000..0bdaeb441a0e23e21f233e16248a28b9fa7d7cbc
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-actions.php
@@ -0,0 +1,123 @@
+<?php
+
+/**
+ * BuddyPress Notifications Actions
+ *
+ * Action functions are exactly the same as screen functions, however they do not
+ * have a template screen associated with them. Usually they will send the user
+ * back to the default screen after execution.
+ *
+ * @package BuddyPress
+ * @subpackage NotificationsActions
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+/**
+ * Handle marking single notifications as read.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return boolean
+ */
+function bp_notifications_action_mark_read() {
+
+	// Bail if not the unread screen
+	if ( ! bp_is_notifications_component() || ! bp_is_current_action( 'unread' ) ) {
+		return false;
+	}
+
+	// Get the action
+	$action = !empty( $_GET['action']          ) ? $_GET['action']          : '';
+	$nonce  = !empty( $_GET['_wpnonce']        ) ? $_GET['_wpnonce']        : '';
+	$id     = !empty( $_GET['notification_id'] ) ? $_GET['notification_id'] : '';
+
+	// Bail if no action or no ID
+	if ( ( 'read' !== $action ) || empty( $id ) || empty( $nonce ) ) {
+		return false;
+	}
+
+	// Check the nonce and mark the notification
+	if ( bp_verify_nonce_request( 'bp_notification_mark_read_' . $id ) && bp_notifications_mark_notification( $id, false ) ) {
+		bp_core_add_message( __( 'Notification successfully marked read.',         'buddypress' )          );
+	} else {
+		bp_core_add_message( __( 'There was a problem marking that notification.', 'buddypress' ), 'error' );
+	}
+
+	// Redirect
+	bp_core_redirect( bp_displayed_user_domain() . bp_get_notifications_slug() . '/unread/' );
+}
+add_action( 'bp_actions', 'bp_notifications_action_mark_read' );
+
+/**
+ * Handle marking single notifications as unread.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return boolean
+ */
+function bp_notifications_action_mark_unread() {
+
+	// Bail if not the read screen
+	if ( ! bp_is_notifications_component() || ! bp_is_current_action( 'read' ) ) {
+		return false;
+	}
+
+	// Get the action
+	$action = !empty( $_GET['action']          ) ? $_GET['action']          : '';
+	$nonce  = !empty( $_GET['_wpnonce']        ) ? $_GET['_wpnonce']        : '';
+	$id     = !empty( $_GET['notification_id'] ) ? $_GET['notification_id'] : '';
+
+	// Bail if no action or no ID
+	if ( ( 'unread' !== $action ) || empty( $id ) || empty( $nonce ) ) {
+		return false;
+	}
+
+	// Check the nonce and mark the notification
+	if ( bp_verify_nonce_request( 'bp_notification_mark_unread_' . $id ) && bp_notifications_mark_notification( $id, true ) ) {
+		bp_core_add_message( __( 'Notification successfully marked unread.',       'buddypress' )          );
+	} else {
+		bp_core_add_message( __( 'There was a problem marking that notification.', 'buddypress' ), 'error' );
+	}
+
+	// Redirect
+	bp_core_redirect( bp_displayed_user_domain() . bp_get_notifications_slug() . '/read/' );
+}
+add_action( 'bp_actions', 'bp_notifications_action_mark_unread' );
+
+/**
+ * Handle deleting single notifications.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return boolean
+ */
+function bp_notifications_action_delete() {
+
+	// Bail if not the read or unread screen
+	if ( ! bp_is_notifications_component() || ! ( bp_is_current_action( 'read' ) || bp_is_current_action( 'unread' ) ) ) {
+		return false;
+	}
+
+	// Get the action
+	$action = !empty( $_GET['action']          ) ? $_GET['action']          : '';
+	$nonce  = !empty( $_GET['_wpnonce']        ) ? $_GET['_wpnonce']        : '';
+	$id     = !empty( $_GET['notification_id'] ) ? $_GET['notification_id'] : '';
+
+	// Bail if no action or no ID
+	if ( ( 'delete' !== $action ) || empty( $id ) || empty( $nonce ) ) {
+		return false;
+	}
+
+	// Check the nonce and delete the notification
+	if ( bp_verify_nonce_request( 'bp_notification_delete_' . $id ) && bp_notifications_delete_notification( $id ) ) {
+		bp_core_add_message( __( 'Notification successfully deleted.',              'buddypress' )          );
+	} else {
+		bp_core_add_message( __( 'There was a problem deleting that notification.', 'buddypress' ), 'error' );
+	}
+
+	// Redirect
+	bp_core_redirect( bp_displayed_user_domain() . bp_get_notifications_slug() . '/' . bp_current_action() . '/' );
+}
+add_action( 'bp_actions', 'bp_notifications_action_delete' );
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-adminbar.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-adminbar.php
new file mode 100644
index 0000000000000000000000000000000000000000..14a2697ff9eda05c5cd287558b25784e546c9fd2
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-adminbar.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * BuddyPress Notifications Admin Bar functions.
+ *
+ * Admin Bar functions for the Notifications component.
+ *
+ * @package BuddyPress
+ * @subpackage NotificationsToolbar
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+/**
+ * Build the "Notifications" dropdown.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_toolbar_menu() {
+	global $wp_admin_bar;
+
+	if ( ! is_user_logged_in() ) {
+		return false;
+	}
+
+	$notifications = bp_notifications_get_notifications_for_user( bp_loggedin_user_id(), 'object' );
+	$count         = ! empty( $notifications ) ? count( $notifications ) : 0;
+	$alert_class   = (int) $count > 0 ? 'pending-count alert' : 'count no-alert';
+	$menu_title    = '<span id="ab-pending-notifications" class="' . $alert_class . '">' . number_format_i18n( $count ) . '</span>';
+	$menu_link     = trailingslashit( bp_loggedin_user_domain() . bp_get_notifications_slug() );
+
+	// Add the top-level Notifications button
+	$wp_admin_bar->add_menu( array(
+		'parent'    => 'top-secondary',
+		'id'        => 'bp-notifications',
+		'title'     => $menu_title,
+		'href'      => $menu_link,
+	) );
+
+	if ( ! empty( $notifications ) ) {
+		foreach ( (array) $notifications as $notification ) {
+			$wp_admin_bar->add_menu( array(
+				'parent' => 'bp-notifications',
+				'id'     => 'notification-' . $notification->id,
+				'title'  => $notification->content,
+				'href'   => $notification->href,
+			) );
+		}
+	} else {
+		$wp_admin_bar->add_menu( array(
+			'parent' => 'bp-notifications',
+			'id'     => 'no-notifications',
+			'title'  => __( 'No new notifications', 'buddypress' ),
+			'href'   => $menu_link,
+		) );
+	}
+
+	return;
+}
+add_action( 'admin_bar_menu', 'bp_members_admin_bar_notifications_menu', 90 );
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-buddybar.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-buddybar.php
new file mode 100644
index 0000000000000000000000000000000000000000..d49bd94349881ace89e9c60673c35790ea795ae1
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-buddybar.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * BuddyPress Notifications Navigational Functions.
+ *
+ * Sets up navigation elements, including BuddyBar functionality, for the
+ * Notifications component.
+ *
+ * @package BuddyPress
+ * @subpackage NotificationsBuddyBar
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+/**
+ * Create the Notifications menu for the BuddyBar.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_buddybar_menu() {
+
+	if ( ! is_user_logged_in() ) {
+		return false;
+	}
+
+	echo '<li id="bp-adminbar-notifications-menu"><a href="' . esc_url( bp_loggedin_user_domain() ) . '">';
+	_e( 'Notifications', 'buddypress' );
+
+	if ( $notification_count = bp_notifications_get_unread_notification_count( bp_loggedin_user_id() ) ) : ?>
+		<span><?php echo bp_core_number_format( $notification_count ); ?></span>
+	<?php
+	endif;
+
+	echo '</a>';
+	echo '<ul>';
+
+	if ( $notifications = bp_notifications_get_notifications_for_user( bp_loggedin_user_id() ) ) {
+		$counter = 0;
+		for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) {
+			$alt = ( 0 == $counter % 2 ) ? ' class="alt"' : ''; ?>
+
+			<li<?php echo $alt ?>><?php echo $notifications[$i] ?></li>
+
+			<?php $counter++;
+		}
+	} else { ?>
+
+		<li><a href="<?php echo esc_url( bp_loggedin_user_domain() ); ?>"><?php _e( 'No new notifications.', 'buddypress' ); ?></a></li>
+
+	<?php
+	}
+
+	echo '</ul>';
+	echo '</li>';
+}
+add_action( 'bp_adminbar_menus', 'bp_adminbar_notifications_menu', 8 );
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-cache.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-cache.php
new file mode 100644
index 0000000000000000000000000000000000000000..0196f41993401d9cf25f7d22abbebd54cd3f123e
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-cache.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * Functions related to notifications caching.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+
+/**
+ * Invalidate 'all_for_user_' cache when saving.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param BP_Notification_Notification $n Notification object.
+ */
+function bp_notifications_clear_all_for_user_cache_after_save( BP_Notifications_Notification $n ) {
+	wp_cache_delete( 'all_for_user_' . $n->user_id, 'bp_notifications' );
+}
+add_action( 'bp_notification_after_save', 'bp_notifications_clear_all_for_user_cache_after_save' );
+
+/**
+ * Invalidate the 'all_for_user_' cache when deleting.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $args Notification deletion arguments.
+ */
+function bp_notifications_clear_all_for_user_cache_before_delete( $args ) {
+	// Pull up a list of items matching the args (those about te be deleted)
+	$ns = BP_Notifications_Notification::get( $args );
+
+	$user_ids = array();
+	foreach ( $ns as $n ) {
+		$user_ids[] = $n->user_id;
+	}
+
+	foreach ( array_unique( $user_ids ) as $user_id ) {
+		wp_cache_delete( 'all_for_user_' . $user_id, 'bp_notifications' );
+	}
+}
+add_action( 'bp_notification_before_delete', 'bp_notifications_clear_all_for_user_cache_before_delete' );
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-classes.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-classes.php
new file mode 100644
index 0000000000000000000000000000000000000000..09fcf8852b519d663905912f6c542656cbc68de6
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-classes.php
@@ -0,0 +1,924 @@
+<?php
+
+/**
+ * BuddyPress Notifications Classes
+ *
+ * Classes used for the Notifications component.
+ *
+ * @package BuddyPress
+ * @subpackage NotificationsClasses
+ *
+ * @since BuddyPress (1.9.0)
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+/**
+ * BuddyPress Notification items.
+ *
+ * Use this class to create, access, edit, or delete BuddyPress Notifications.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+class BP_Notifications_Notification {
+
+	/**
+	 * The notification ID.
+	 *
+	 * @var int
+	 */
+	public $id;
+
+	/**
+	 * The ID of the item associated with the notification.
+	 *
+	 * @var int
+	 */
+	public $item_id;
+
+	/**
+	 * The ID of the secondary item associated with the notification.
+	 *
+	 * @var int
+	 */
+	public $secondary_item_id = null;
+
+	/**
+	 * The ID of the user the notification is associated with.
+	 *
+	 * @var int
+	 */
+	public $user_id;
+
+	/**
+	 * The name of the component that the notification is for.
+	 *
+	 * @var string
+	 */
+	public $component_name;
+
+	/**
+	 * The component action which the notification is related to.
+	 *
+	 * @var string
+	 */
+	public $component_action;
+
+	/**
+	 * The date the notification was created.
+	 *
+	 * @var string
+	 */
+	public $date_notified;
+
+	/**
+	 * Is the notification new, or has it already been read.
+	 *
+	 * @var bool
+	 */
+	public $is_new;
+
+	/** Public Methods ****************************************************/
+
+	/**
+	 * Constructor method.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param int $id Optional. Provide an ID to access an existing
+	 *        notification item.
+	 */
+	public function __construct( $id = 0 ) {
+		if ( ! empty( $id ) ) {
+			$this->id = $id;
+			$this->populate();
+		}
+	}
+
+	/**
+	 * Update or insert notification details into the database.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @global wpdb $wpdb WordPress database object.
+	 *
+	 * @return bool True on success, false on failure.
+	 */
+	public function save() {
+
+		// Return value
+		$retval = false;
+
+		// Default data and format
+		$data = array(
+			'user_id'           => $this->user_id,
+			'item_id'           => $this->item_id,
+			'secondary_item_id' => $this->secondary_item_id,
+			'component_name'    => $this->component_name,
+			'component_action'  => $this->component_action,
+			'date_notified'     => $this->date_notified,
+			'is_new'            => $this->is_new,
+		);
+		$data_format = array( '%d', '%d', '%d', '%s', '%s', '%s', '%d' );
+
+		do_action_ref_array( 'bp_notification_before_save', array( &$this ) );
+
+		// Update
+		if ( ! empty( $this->id ) ) {
+			$result = self::_update( $data, array( 'ID' => $this->id ), $data_format, array( '%d' ) );
+
+		// Insert
+		} else {
+			$result = self::_insert( $data, $data_format );
+		}
+
+		// Set the notification ID if successful
+		if ( ! empty( $result ) && ! is_wp_error( $result ) ) {
+			global $wpdb;
+
+			$this->id = $wpdb->insert_id;
+			$retval   = $wpdb->insert_id;
+		}
+
+		do_action_ref_array( 'bp_notification_after_save', array( &$this ) );
+
+		// Return the result
+		return $retval;
+	}
+
+	/**
+	 * Fetch data for an existing notification from the database.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @global BuddyPress $bp The one true BuddyPress instance.
+	 * @global wpdb $wpdb WordPress database object.
+	 */
+	public function populate() {
+		global $wpdb;
+
+		$bp = buddypress();
+
+		// Look for a notification
+		$notification = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->notifications->table_name} WHERE id = %d", $this->id ) );
+
+		// Setup the notification data
+		if ( ! empty( $notification ) && ! is_wp_error( $notification ) ) {
+			$this->item_id           = $notification->item_id;
+			$this->secondary_item_id = $notification->secondary_item_id;
+			$this->user_id           = $notification->user_id;
+			$this->component_name    = $notification->component_name;
+			$this->component_action  = $notification->component_action;
+			$this->date_notified     = $notification->date_notified;
+			$this->is_new            = $notification->is_new;
+		}
+	}
+
+	/** Protected Static Methods ******************************************/
+
+	/**
+	 * Create a notification entry.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param array $data {
+	 *     Array of notification data, passed to {@link wpdb::insert()}.
+	 *     @type int $user_id ID of the associated user.
+	 *     @type int $item_id ID of the associated item.
+	 *     @type int $secondary_item_id ID of the secondary associated item.
+	 *     @type string $component_name Name of the associated component.
+	 *     @type string $component_action Name of the associated component
+	 *           action.
+	 *     @type string $date_notified Timestamp of the notification.
+	 *     @type bool $is_new True if the notification is unread, otherwise
+	 *           false.
+	 * }
+	 * @param array $data_format See {@link wpdb::insert()}.
+	 * @return int|false The number of rows inserted, or false on error.
+	 */
+	protected static function _insert( $data = array(), $data_format = array() ) {
+		global $wpdb;
+		return $wpdb->insert( buddypress()->notifications->table_name, $data, $data_format );
+	}
+
+	/**
+	 * Update notifications.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see wpdb::update() for further description of paramater formats.
+	 *
+	 * @param array $data Array of notification data to update, passed to
+	 *        {@link wpdb::update()}. Accepts any property of a
+	 *        BP_Notification_Notification object.
+	 * @param array $where The WHERE params as passed to wpdb::update().
+	 *        Typically consists of array( 'ID' => $id ) to specify the ID
+	 *        of the item being updated. See {@link wpdb::update()}.
+	 * @param array $data_format See {@link wpdb::insert()}.
+	 * @param array $where_format See {@link wpdb::insert()}.
+	 * @return int|false The number of rows updated, or false on error.
+	 */
+	protected static function _update( $data = array(), $where = array(), $data_format = array(), $where_format = array() ) {
+		global $wpdb;
+		return $wpdb->update( buddypress()->notifications->table_name, $data, $where, $data_format, $where_format );
+	}
+
+	/**
+	 * Delete notifications.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see wpdb::update() for further description of paramater formats.
+	 *
+	 * @param array $where Array of WHERE clauses to filter by, passed to
+	 *        {@link wpdb::delete()}. Accepts any property of a
+	 *        BP_Notification_Notification object.
+	 * @param array $where_format See {@link wpdb::insert()}.
+	 * @return int|false The number of rows updated, or false on error.
+	 */
+	protected static function _delete( $where = array(), $where_format = array() ) {
+		global $wpdb;
+		return $wpdb->delete( buddypress()->notifications->table_name, $where, $where_format );
+	}
+
+	/**
+	 * Assemble the WHERE clause of a get() SQL statement.
+	 *
+	 * Used by BP_Notifications_Notification::get() to create its WHERE
+	 * clause.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param array $args See {@link BP_Notifications_Notification::get()}
+	 *        for more details.
+	 * @return string WHERE clause.
+	 */
+	protected static function get_where_sql( $args = array() ) {
+		global $wpdb;
+
+		$where_conditions = array();
+		$where            = '';
+
+		// id
+		if ( ! empty( $args['id'] ) ) {
+			$id_in = implode( ',', wp_parse_id_list( $args['id'] ) );
+			$where_conditions['id'] = "id IN ({$id_in})";
+		}
+
+		// user_id
+		if ( ! empty( $args['user_id'] ) ) {
+			$user_id_in = implode( ',', wp_parse_id_list( $args['user_id'] ) );
+			$where_conditions['user_id'] = "user_id IN ({$user_id_in})";
+		}
+
+		// item_id
+		if ( ! empty( $args['item_id'] ) ) {
+			$item_id_in = implode( ',', wp_parse_id_list( $args['item_id'] ) );
+			$where_conditions['item_id'] = "item_id IN ({$item_id_in})";
+		}
+
+		// secondary_item_id
+		if ( ! empty( $args['secondary_item_id'] ) ) {
+			$secondary_item_id_in = implode( ',', wp_parse_id_list( $args['secondary_item_id'] ) );
+			$where_conditions['secondary_item_id'] = "secondary_item_id IN ({$secondary_item_id_in})";
+		}
+
+		// component_name
+		if ( ! empty( $args['component_name'] ) ) {
+			if ( ! is_array( $args['component_name'] ) ) {
+				$component_names = explode( ',', $args['component_name'] );
+			} else {
+				$component_names = $args['component_name'];
+			}
+
+			$cn_clean = array();
+			foreach ( $component_names as $cn ) {
+				$cn_clean[] = $wpdb->prepare( '%s', $cn );
+			}
+
+			$cn_in = implode( ',', $cn_clean );
+			$where_conditions['component_name'] = "component_name IN ({$cn_in})";
+		}
+
+		// component_action
+		if ( ! empty( $args['component_action'] ) ) {
+			if ( ! is_array( $args['component_action'] ) ) {
+				$component_actions = explode( ',', $args['component_action'] );
+			} else {
+				$component_actions = $args['component_action'];
+			}
+
+			$ca_clean = array();
+			foreach ( $component_actions as $ca ) {
+				$ca_clean[] = $wpdb->prepare( '%s', $ca );
+			}
+
+			$ca_in = implode( ',', $ca_clean );
+			$where_conditions['component_action'] = "component_action IN ({$ca_in})";
+		}
+
+		// is_new
+		if ( ! empty( $args['is_new'] ) && 'both' !== $args['is_new'] ) {
+			$where_conditions['is_new'] = "is_new = 1";
+		} elseif ( isset( $args['is_new'] ) && ( 0 === $args['is_new'] || false === $args['is_new'] ) ) {
+			$where_conditions['is_new'] = "is_new = 0";
+		}
+
+		// search_terms
+		if ( ! empty( $args['search_terms'] ) ) {
+			$search_terms = like_escape( esc_sql( $args['search_terms'] ) );
+			$where_conditions['search_terms'] = "( component_name LIKE '%%$search_terms%%' OR component_action LIKE '%%$search_terms%%' )";
+		}
+
+		// Custom WHERE
+		if ( ! empty( $where_conditions ) ) {
+			$where = 'WHERE ' . implode( ' AND ', $where_conditions );
+		}
+
+		return $where;
+	}
+
+	/**
+	 * Assemble the ORDER BY clause of a get() SQL statement.
+	 *
+	 * Used by BP_Notifications_Notification::get() to create its ORDER BY
+	 * clause.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param array $args See {@link BP_Notifications_Notification::get()}
+	 *        for more details.
+	 * @return string ORDER BY clause.
+	 */
+	protected static function get_order_by_sql( $args = array() ) {
+
+		// Setup local variable
+		$conditions = array();
+		$retval     = '';
+
+		// Order by
+		if ( ! empty( $args['order_by'] ) ) {
+			$order_by               = implode( ', ', (array) $args['order_by'] );
+			$conditions['order_by'] = "{$order_by}";
+		}
+
+		// Sort order direction
+		if ( ! empty( $args['sort_order'] ) && in_array( $args['sort_order'], array( 'ASC', 'DESC' ) ) ) {
+			$sort_order               = $args['sort_order'];
+			$conditions['sort_order'] = "{$sort_order}";
+		}
+
+		// Custom ORDER BY
+		if ( ! empty( $conditions ) ) {
+			$retval = 'ORDER BY ' . implode( ' ', $conditions );
+		}
+
+		return $retval;
+	}
+
+	/**
+	 * Assemble the LIMIT clause of a get() SQL statement.
+	 *
+	 * Used by BP_Notifications_Notification::get() to create its LIMIT clause.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param array $args See {@link BP_Notifications_Notification::get()}
+	 *        for more details.
+	 * @return string LIMIT clause.
+	 */
+	protected static function get_paged_sql( $args = array() ) {
+		global $wpdb;
+
+		// Setup local variable
+		$retval = '';
+
+		// Custom LIMIT
+		if ( ! empty( $args['page'] ) && ! empty( $args['per_page'] ) ) {
+			$page     = absint( $args['page']     );
+			$per_page = absint( $args['per_page'] );
+			$offset   = $per_page * ( $page - 1 );
+			$retval   = $wpdb->prepare( "LIMIT %d, %d", $offset, $per_page );
+		}
+
+		return $retval;
+	}
+
+	/**
+	 * Assemble query clauses, based on arrguments, to pass to $wpdb methods.
+	 *
+	 * The insert(), update(), and delete() methods of {@link wpdb} expect
+	 * arguments of the following forms:
+	 *
+	 * - associative arrays whose key/value pairs are column => value, to
+	 *   be used in WHERE, SET, or VALUES clauses
+	 * - arrays of "formats", which tell $wpdb->prepare() which type of
+	 *   value to expect when sanitizing (eg, array( '%s', '%d' ))
+	 *
+	 * This utility method can be used to assemble both kinds of params,
+	 * out of a single set of associative array arguments, such as:
+	 *
+	 *     $args = array(
+	 *         'user_id' => 4,
+	 *         'component_name' => 'groups',
+	 *     );
+	 *
+	 * This will be converted to:
+	 *
+	 *     array(
+	 *         'data' => array(
+	 *             'user_id' => 4,
+	 *             'component_name' => 'groups',
+	 *         ),
+	 *         'format' => array(
+	 *             '%d',
+	 *             '%s',
+	 *         ),
+	 *     )
+	 *
+	 * which can easily be passed as arguments to the $wpdb methods.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param $args Associative array of filter arguments.
+	 *        See {@BP_Notifications_Notification::get()} for a breakdown.
+	 * @return array Associative array of 'data' and 'format' args.
+	 */
+	protected static function get_query_clauses( $args = array() ) {
+		$where_clauses = array(
+			'data'   => array(),
+			'format' => array(),
+		);
+
+		// id
+		if ( ! empty( $args['id'] ) ) {
+			$where_clauses['data']['id'] = absint( $args['id'] );
+			$where_clauses['format'][] = '%d';
+		}
+
+		// user_id
+		if ( ! empty( $args['user_id'] ) ) {
+			$where_clauses['data']['user_id'] = absint( $args['user_id'] );
+			$where_clauses['format'][] = '%d';
+		}
+
+		// item_id
+		if ( ! empty( $args['item_id'] ) ) {
+			$where_clauses['data']['item_id'] = absint( $args['item_id'] );
+			$where_clauses['format'][] = '%d';
+		}
+
+		// secondary_item_id
+		if ( ! empty( $args['secondary_item_id'] ) ) {
+			$where_clauses['data']['secondary_item_id'] = absint( $args['secondary_item_id'] );
+			$where_clauses['format'][] = '%d';
+		}
+
+		// component_name
+		if ( ! empty( $args['component_name'] ) ) {
+			$where_clauses['data']['component_name'] = $args['component_name'];
+			$where_clauses['format'][] = '%s';
+		}
+
+		// component_action
+		if ( ! empty( $args['component_action'] ) ) {
+			$where_clauses['data']['component_action'] = $args['component_action'];
+			$where_clauses['format'][] = '%s';
+		}
+
+		// is_new
+		if ( isset( $args['is_new'] ) ) {
+			$where_clauses['data']['is_new'] = ! empty( $args['is_new'] ) ? 1 : 0;
+			$where_clauses['format'][] = '%d';
+		}
+
+		return $where_clauses;
+	}
+
+	/** Public Static Methods *********************************************/
+
+	/**
+	 * Check that a specific notification is for a specific user.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param int $user_id ID of the user being checked.
+	 * @param int $notification_id ID of the notification being checked.
+	 * @return bool True if the notification belongs to the user, otherwise
+	 *         false.
+	 */
+	public static function check_access( $user_id, $notification_id ) {
+		global $wpdb;
+
+		$bp = buddypress();
+
+		return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->core->table_name_notifications} WHERE id = %d AND user_id = %d", $notification_id, $user_id ) );
+	}
+
+	/**
+	 * Get notifications, based on provided filter parameters.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param array $args {
+	 *     Associative array of arguments. All arguments but $page and
+	 *     $per_page can be treated as filter values for get_where_sql()
+	 *     and get_query_clauses(). All items are optional.
+	 *     @type int|array $id ID of notification being updated. Can be an
+	 *           array of IDs.
+	 *     @type int|array $user_id ID of user being queried. Can be an
+	 *           array of user IDs.
+	 *     @type int|array $item_id ID of associated item. Can be an array
+	 *           of multiple item IDs.
+	 *     @type int|array $secondary_item_id ID of secondary associated
+	 *           item. Can be an array of multiple IDs.
+	 *     @type string|array $component_name Name of the component to
+	 *           filter by. Can be an array of component names.
+	 *     @type string|array $component_action Name of the action to
+	 *           filter by. Can be an array of actions.
+	 *     @type bool $is_new Whether to limit to new notifications. True
+	 *           returns only new notifications, false returns only non-new
+	 *           notifications. 'both' returns all. Default: true.
+	 *     @type string $search_terms Term to match against component_name
+	 *           or component_action fields.
+	 *     @type string $order_by Field to order results by.
+	 *     @type string $sort_order ASC or DESC.
+	 *     @type int $page Number of the current page of results. Default:
+	 *           false (no pagination - all items).
+	 *     @type int $per_page Number of items to show per page. Default:
+	 *           false (no pagination - all items).
+	 * }
+	 * @return array Located notifications.
+	 */
+	public static function get( $args = array() ) {
+		global $wpdb;
+
+		// Parse the arguments
+		$r  = wp_parse_args( $args, array(
+			'id'                => false,
+			'user_id'           => false,
+			'item_id'           => false,
+			'secondary_item_id' => false,
+			'component_name'    => bp_notifications_get_registered_components(),
+			'component_action'  => false,
+			'is_new'            => true,
+			'search_terms'      => '',
+			'order_by'          => false,
+			'sort_order'        => false,
+			'page'              => false,
+			'per_page'          => false,
+		) );
+
+		// SELECT
+		$select_sql = "SELECT *";
+
+		// FROM
+		$from_sql   = "FROM " . buddypress()->notifications->table_name;
+
+		// WHERE
+		$where_sql  = self::get_where_sql( array(
+			'id'                => $r['id'],
+			'user_id'           => $r['user_id'],
+			'item_id'           => $r['item_id'],
+			'secondary_item_id' => $r['secondary_item_id'],
+			'component_name'    => $r['component_name'],
+			'component_action'  => $r['component_action'],
+			'is_new'            => $r['is_new'],
+			'search_terms'      => $r['search_terms'],
+		) );
+
+		// ORDER BY
+		$order_sql  = self::get_order_by_sql( array(
+			'order_by'   => $r['order_by'],
+			'sort_order' => $r['sort_order']
+		) );
+
+		// LIMIT %d, %d
+		$pag_sql    = self::get_paged_sql( array(
+			'page'     => $r['page'],
+			'per_page' => $r['per_page'],
+		) );
+
+		$sql = "{$select_sql} {$from_sql} {$where_sql} {$order_sql} {$pag_sql}";
+
+		return $wpdb->get_results( $sql );
+	}
+
+	/**
+	 * Get a count of total notifications matching a set of arguments.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see BP_Notifications_Notification::get() for a description of
+	 *      arguments.
+	 *
+	 * @param array $args See {@link BP_Notifications_Notification::get()}.
+	 * @return int Count of located items.
+	 */
+	public static function get_total_count( $args ) {
+		global $wpdb;
+
+		/**
+		 * Default component_name to active_components
+		 *
+		 * @see http://buddypress.trac.wordpress.org/ticket/5300
+		 */
+		$args = wp_parse_args( $args, array(
+			'component_name' => bp_notifications_get_registered_components()
+		) );
+
+		// Load BuddyPress
+		$bp = buddypress();
+
+		// Build the query
+		$select_sql = "SELECT COUNT(*)";
+		$from_sql   = "FROM {$bp->notifications->table_name}";
+		$where_sql  = self::get_where_sql( $args );
+		$sql        = "{$select_sql} {$from_sql} {$where_sql}";
+
+		// Return the queried results
+		return $wpdb->get_var( $sql );
+	}
+
+	/**
+	 * Update notifications.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see BP_Notifications_Notification::get() for a description of
+	 *      accepted update/where arguments.
+	 *
+	 * @param array $update_args Associative array of fields to update,
+	 *        and the values to update them to. Of the format
+	 *            array( 'user_id' => 4, 'component_name' => 'groups', )
+	 * @param array $where_args Associative array of columns/values, to
+	 *        determine which rows should be updated. Of the format
+	 *            array( 'item_id' => 7, 'component_action' => 'members', )
+	 * @return int|bool Number of rows updated on success, false on failure.
+	 */
+	public static function update( $update_args = array(), $where_args = array() ) {
+		$update = self::get_query_clauses( $update_args );
+		$where  = self::get_query_clauses( $where_args  );
+
+		// make sure we delete the notification cache for the user on update
+		if ( ! empty( $where_args['user_id'] ) ) {
+			wp_cache_delete( 'all_for_user_' . $where_args['user_id'], 'bp_notifications' );
+		}
+
+		return self::_update( $update['data'], $where['data'], $update['format'], $where['format'] );
+	}
+
+	/**
+	 * Delete notifications.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see BP_Notifications_Notification::get() for a description of
+	 *      accepted update/where arguments.
+	 *
+	 * @param array $args Associative array of columns/values, to determine
+	 *        which rows should be deleted.  Of the format
+	 *            array( 'item_id' => 7, 'component_action' => 'members', )
+	 * @return int|bool Number of rows deleted on success, false on failure.
+	 */
+	public static function delete( $args = array() ) {
+		$where = self::get_query_clauses( $args );
+
+		do_action( 'bp_notification_before_delete', $args );
+
+		return self::_delete( $where['data'], $where['format'] );
+	}
+
+	/** Convenience methods ***************************************************/
+
+	/**
+	 * Delete a single notification by ID.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see BP_Notifications_Notification::delete() for explanation of
+	 *      return value.
+	 *
+	 * @param int $id ID of the notification item to be deleted.
+	 * @return bool True on success, false on failure.
+	 */
+	public static function delete_by_id( $id ) {
+		return self::delete( array(
+			'id' => $id,
+		) );
+	}
+
+	/**
+	 * Fetch all the notifications in the database for a specific user.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param int $user_id ID of the user whose notifications are being
+	 *        fetched.
+	 * @param string $status Optional. Status of notifications to fetch.
+	 *        'is_new' to get only unread items, 'all' to get all.
+	 * @return array Associative array of notification items.
+	 */
+	public static function get_all_for_user( $user_id, $status = 'is_new' ) {
+		return self::get( array(
+			'user_id' => $user_id,
+			'is_new'  => 'is_new' === $status,
+		) );
+	}
+
+	/**
+	 * Fetch all the unread notifications in the database for a specific user.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param int $user_id ID of the user whose notifications are being
+	 *        fetched.
+	 * @return array Associative array of unread notification items.
+	 */
+	public static function get_unread_for_user( $user_id = 0 ) {
+		return self::get( array(
+			'user_id' => $user_id,
+			'is_new'  => true,
+		) );
+	}
+
+	/**
+	 * Fetch all the read notifications in the database for a specific user.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param int $user_id ID of the user whose notifications are being
+	 *        fetched.
+	 * @return array Associative array of unread notification items.
+	 */
+	public static function get_read_for_user( $user_id = 0 ) {
+		return self::get( array(
+			'user_id' => $user_id,
+			'is_new'  => false,
+		) );
+	}
+
+	/**
+	 * Get unread notifications for a user, in a pagination-friendly format.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param array $args {
+	 *     Array of arguments.
+	 *     @type int $user_id ID of the user for whom the notifications are
+	 *           being fetched. Default: logged-in user ID.
+	 *     @type bool $is_new Whether to limit the query to unread
+	 *           notifications. Default: true.
+	 *     @type int $page Number of the page to return. Default: 1.
+	 *     @type int $per_page Number of results to display per page.
+	 *           Default: 10.
+	 *     @type string $search_terms Optional. A term to search against in
+	 *           the 'component_name' and 'component_action' columns.
+	 * }
+	 * @return array {
+	 *     @type array $notifications Array of notification results.
+	 *     @type int $total Count of all located notifications matching
+	 *           the query params.
+	 * }
+	 */
+	public static function get_current_notifications_for_user( $args = array() ) {
+		$r = wp_parse_args( $args, array(
+			'user_id'      => bp_loggedin_user_id(),
+			'is_new'       => true,
+			'page'         => 1,
+			'per_page'     => 25,
+			'search_terms' => '',
+		) );
+
+		$notifications = self::get( $r );
+
+		// Bail if no notifications
+		if ( empty( $notifications ) ) {
+			return false;
+		}
+
+		$total_count = self::get_total_count( $r );
+
+		return array( 'notifications' => &$notifications, 'total' => $total_count );
+	}
+
+	/** Mark ******************************************************************/
+
+	/**
+	 * Mark all user notifications as read.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param int $user_id The ID of the user who the notifications
+	 *        are for.
+	 * @param int $is_new Mark as read (1) or unread (0).
+	 */
+	public static function mark_all_for_user( $user_id, $is_new = 0, $item_id = 0, $component_name = '', $component_action = '', $secondary_item_id = 0 ) {
+
+		// Values to be updated
+		$update_args = array(
+			'is_new' => $is_new,
+		);
+
+		// WHERE clauses
+		$where_args = array(
+			'user_id' => $user_id,
+		);
+
+		if ( ! empty( $item_id ) ) {
+			$where_args['item_id'] = $item_id;
+		}
+
+		if ( ! empty( $component_name ) ) {
+			$where_args['component_name'] = $component_name;
+		}
+
+		if ( ! empty( $component_action ) ) {
+			$where_args['component_action'] = $component_action;
+		}
+
+		if ( ! empty( $secondary_item_id ) ) {
+			$where_args['secondary_item_id'] = $secondary_item_id;
+		}
+
+		return self::update( $update_args, $where_args );
+	}
+
+	/**
+	 * Mark all notifications from a user as read.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param int $user_id The ID of the user who the notifications are from.
+	 * @param int $is_new Mark as read (1) or unread (0).
+	 */
+	public static function mark_all_from_user( $user_id, $is_new = 0, $component_name = '', $component_action = '', $secondary_item_id = 0 ) {
+
+		// Values to be updated
+		$update_args = array(
+			'is_new' => $is_new,
+		);
+
+		// WHERE clauses
+		$where_args = array(
+			'item_id' => $user_id,
+		);
+
+		if ( ! empty( $component_name ) ) {
+			$where_args['component_name'] = $component_name;
+		}
+
+		if ( ! empty( $component_action ) ) {
+			$where_args['component_action'] = $component_action;
+		}
+
+		if ( ! empty( $secondary_item_id ) ) {
+			$where_args['secondary_item_id'] = $secondary_item_id;
+		}
+
+		return self::update( $update_args, $where_args );
+	}
+
+	/**
+	 * Mark all notifications for all users as read by item id, and optional
+	 * secondary item id, and component name and action.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param int $item_id The ID of the item associated with the
+	 *        notifications.
+	 * @param string $component_name The component that the notifications
+	 *        are associated with.
+	 * @param string $component_action The action that the notifications
+	 *        are associated with.
+	 * @param string $secondary_item_id Optional. ID of the secondary
+	 *        associated item.
+	 */
+	public static function mark_all_by_type( $item_id, $is_new = 0, $component_name = '', $component_action = '', $secondary_item_id = 0 ) {
+
+		// Values to be updated
+		$update_args = array(
+			'is_new' => $is_new,
+		);
+
+		// WHERE clauses
+		$where_args = array(
+			'item_id' => $item_id,
+		);
+
+		if ( ! empty( $component_name ) ) {
+			$where_args['component_name'] = $component_name;
+		}
+
+		if ( ! empty( $component_action ) ) {
+			$where_args['component_action'] = $component_action;
+		}
+
+		if ( ! empty( $secondary_item_id ) ) {
+			$where_args['secondary_item_id'] = $secondary_item_id;
+		}
+
+		return self::update( $update_args, $where_args );
+	}
+}
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-functions.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-functions.php
new file mode 100644
index 0000000000000000000000000000000000000000..d7c1f346e664096b24429a952f799500042e1c0b
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-functions.php
@@ -0,0 +1,569 @@
+<?php
+
+/**
+ * BuddyPress Member Notifications Functions.
+ *
+ * Functions and filters used in the Notifications component.
+ *
+ * @package BuddyPress
+ * @subpackage NotificationsFunctions
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+/**
+ * Add a notification for a specific user, from a specific component.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param array $args {
+ *     Array of arguments describing the notification. All are optional.
+ *     @type int $user_id ID of the user to associate the notificiton with.
+ *     @type int $item_id ID of the item to associate the notification with.
+ *     @type int $secondary_item_id ID of the secondary item to associate the
+ *           notification with.
+ *     @type string $component_name Name of the component to associate the
+ *           notification with.
+ *     @type string $component_action Name of the action to associate the
+ *           notification with.
+ *     @type string $date_notified Timestamp for the notification.
+ * }
+ * @return int|bool ID of the newly created notification on success, false
+ *         on failure.
+ */
+function bp_notifications_add_notification( $args = array() ) {
+
+	$r = wp_parse_args( $args, array(
+		'user_id'           => 0,
+		'item_id'           => 0,
+		'secondary_item_id' => 0,
+		'component_name'    => '',
+		'component_action'  => '',
+		'date_notified'     => bp_core_current_time(),
+		'is_new'            => 1,
+		'allow_duplicate'   => false,
+	) );
+
+	// Check for existing duplicate notifications
+	if ( ! $r['allow_duplicate'] ) {
+		// date_notified, allow_duplicate don't count toward
+		// duplicate status
+		$existing = BP_Notifications_Notification::get( array(
+			'user_id'           => $r['user_id'],
+			'item_id'           => $r['item_id'],
+			'secondary_item_id' => $r['secondary_item_id'],
+			'component_name'    => $r['component_name'],
+			'component_action'  => $r['component_action'],
+			'is_new'            => $r['is_new'],
+		) );
+
+		if ( ! empty( $existing ) ) {
+			return false;
+		}
+	}
+
+	// Setup the new notification
+	$notification                    = new BP_Notifications_Notification;
+	$notification->user_id           = $r['user_id'];
+	$notification->item_id           = $r['item_id'];
+	$notification->secondary_item_id = $r['secondary_item_id'];
+	$notification->component_name    = $r['component_name'];
+	$notification->component_action  = $r['component_action'];
+	$notification->date_notified     = $r['date_notified'];
+	$notification->is_new            = $r['is_new'];
+
+	// Save the new notification
+	return $notification->save();
+}
+
+/**
+ * Get a specific notification by its ID.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $id ID of the notification.
+ * @return BP_Notifications_Notification
+ */
+function bp_notifications_get_notification( $id ) {
+	return new BP_Notifications_Notification( $id );
+}
+
+/**
+ * Delete a specific notification by its ID.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $id ID of the notification to delete.
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_delete_notification( $id ) {
+	if ( ! bp_notifications_check_notification_access( bp_loggedin_user_id(), $id ) ) {
+		return false;
+	}
+
+	return BP_Notifications_Notification::delete( array( 'id' => $id ) );
+}
+
+/**
+ * Mark notification read/unread for a user by ID.
+ *
+ * Used when clearing out notifications for a specific notification item.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose notifications are being deleted.
+ * @param int $is_new 0 for read, 1 for unread
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_mark_notification( $id, $is_new = false ) {
+	if ( ! bp_notifications_check_notification_access( bp_loggedin_user_id(), $id ) ) {
+		return false;
+	}
+
+	return BP_Notifications_Notification::update(
+		array( 'is_new' => $is_new ),
+		array( 'id'     => $id     )
+	);
+}
+
+/**
+ * Get notifications for a specific user.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose notification are being fetched.
+ * @param string $format Format of the returned values. 'string' returns HTML,
+ *        while 'object' returns a structured object for parsing.
+ * @return mixed Object or array on success, false on failure.
+ */
+function bp_notifications_get_notifications_for_user( $user_id, $format = 'string' ) {
+
+	// Setup local variables
+	$bp = buddypress();
+
+	// Get notifications out of the cache, or query if necessary
+	$notifications = wp_cache_get( 'all_for_user_' . $user_id, 'bp_notifications' );
+	if ( false === $notifications ) {
+		$notifications = BP_Notifications_Notification::get( array(
+			'user_id' => $user_id
+		) );
+		wp_cache_set( 'all_for_user_' . $user_id, $notifications, 'bp_notifications' );
+	}
+
+	$grouped_notifications = array(); // Notification groups
+	$renderable            = array(); // Renderable notifications
+
+	// Group notifications by component and component_action and provide totals
+	for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) {
+		$notification = $notifications[$i];
+		$grouped_notifications[$notification->component_name][$notification->component_action][] = $notification;
+	}
+
+	// Bail if no notification groups
+	if ( empty( $grouped_notifications ) ) {
+		return false;
+	}
+
+	// Calculate a renderable output for each notification type
+	foreach ( $grouped_notifications as $component_name => $action_arrays ) {
+
+		// Skip if group is empty
+		if ( empty( $action_arrays ) ) {
+			continue;
+		}
+
+		// Loop through each actionable item and try to map it to a component
+		foreach ( (array) $action_arrays as $component_action_name => $component_action_items ) {
+
+			// Get the number of actionable items
+			$action_item_count = count( $component_action_items );
+
+			// Skip if the count is less than 1
+			if ( $action_item_count < 1 ) {
+				continue;
+			}
+
+			// Callback function exists
+			if ( isset( $bp->{$component_name}->notification_callback ) && is_callable( $bp->{$component_name}->notification_callback ) ) {
+
+				// Function should return an object
+				if ( 'object' === $format ) {
+
+					// Retrieve the content of the notification using the callback
+					$content = call_user_func(
+						$bp->{$component_name}->notification_callback,
+						$component_action_name,
+						$component_action_items[0]->item_id,
+						$component_action_items[0]->secondary_item_id,
+						$action_item_count,
+						'array'
+					);
+
+					// Create the object to be returned
+					$notification_object = new stdClass;
+
+					// Minimal backpat with non-compatible notification
+					// callback functions
+					if ( is_string( $content ) ) {
+						$notification_object->content = $content;
+						$notification_object->href    = bp_loggedin_user_domain();
+					} else {
+						$notification_object->content = $content['text'];
+						$notification_object->href    = $content['link'];
+					}
+
+					$notification_object->id = $component_action_items[0]->id;
+					$renderable[]            = $notification_object;
+
+				// Return an array of content strings
+				} else {
+					$content      = call_user_func( $bp->{$component_name}->notification_callback, $component_action_name, $component_action_items[0]->item_id, $component_action_items[0]->secondary_item_id, $action_item_count );
+					$renderable[] = $content;
+				}
+
+			// @deprecated format_notification_function - 1.5
+			} elseif ( isset( $bp->{$component_name}->format_notification_function ) && function_exists( $bp->{$component_name}->format_notification_function ) ) {
+				$renderable[] = call_user_func( $bp->{$component_name}->format_notification_function, $component_action_name, $component_action_items[0]->item_id, $component_action_items[0]->secondary_item_id, $action_item_count );
+
+			// Allow non BuddyPress components to hook in
+			} else {
+
+				// The array to reference with apply_filters_ref_array()
+				$ref_array = array(
+					$component_action_name,
+					$component_action_items[0]->item_id,
+					$component_action_items[0]->secondary_item_id,
+					$action_item_count,
+					$format
+				);
+
+				// Function should return an object
+				if ( 'object' === $format ) {
+
+					// Retrieve the content of the notification using the callback
+					$content = apply_filters_ref_array( 'bp_notifications_get_notifications_for_user', $ref_array );
+
+					// Create the object to be returned
+					$notification_object = new stdClass;
+
+					// Minimal backpat with non-compatible notification
+					// callback functions
+					if ( is_string( $content ) ) {
+						$notification_object->content = $content;
+						$notification_object->href    = bp_loggedin_user_domain();
+					} else {
+						$notification_object->content = $content['text'];
+						$notification_object->href    = $content['link'];
+					}
+
+					$notification_object->id = $component_action_items[0]->id;
+					$renderable[]            = $notification_object;
+
+				// Return an array of content strings
+				} else {
+					$renderable[] = apply_filters_ref_array( 'bp_notifications_get_notifications_for_user', $ref_array );
+				}
+			}
+		}
+	}
+
+	// If renderable is empty array, set to false
+	if ( empty( $renderable ) ) {
+		$renderable = false;
+	}
+
+	// Filter and return
+	return apply_filters( 'bp_core_get_notifications_for_user', $renderable, $user_id, $format );
+}
+
+/** Delete ********************************************************************/
+
+/**
+ * Delete notifications for a user by type.
+ *
+ * Used when clearing out notifications for a specific component when the user
+ * has visited that component.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose notifications are being deleted.
+ * @param string $component_name Name of the associated component.
+ * @param string $component_action Name of the associated action.
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_delete_notifications_by_type( $user_id, $component_name, $component_action ) {
+	return BP_Notifications_Notification::delete( array(
+		'user_id'          => $user_id,
+		'component_name'   => $component_name,
+		'component_action' => $component_action,
+	) );
+}
+
+/**
+ * Delete notifications for an item ID.
+ *
+ * Used when clearing out notifications for a specific component when the user
+ * has visited that component.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose notifications are being deleted.
+ * @param int $item_id ID of the associated item.
+ * @param string $component_name Name of the associated component.
+ * @param string $component_action Name of the associated action.
+ * @param int $secondary_item_id ID of the secondary associated item.
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false ) {
+	return BP_Notifications_Notification::delete( array(
+		'user_id'           => $user_id,
+		'item_id'           => $item_id,
+		'secondary_item_id' => $secondary_item_id,
+		'component_name'    => $component_name,
+		'component_action'  => $component_action,
+	) );
+}
+
+/**
+ * Delete all notifications by type.
+ *
+ * Used when clearing out notifications for an entire component.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose notifications are being deleted.
+ * @param string $component_name Name of the associated component.
+ * @param string $component_action Optional. Name of the associated action.
+ * @param int $secondary_item_id Optional. ID of the secondary associated item.
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_delete_all_notifications_by_type( $item_id, $component_name, $component_action = false, $secondary_item_id = false ) {
+	return BP_Notifications_Notification::delete( array(
+		'item_id'           => $item_id,
+		'secondary_item_id' => $secondary_item_id,
+		'component_name'    => $component_name,
+		'component_action'  => $component_action,
+	) );
+}
+
+/**
+ * Delete all notifications from a user.
+ *
+ * Used when clearing out all notifications for a user, when deleted or spammed.
+ *
+ * @todo This function assumes that items with the user_id in the item_id slot
+ *       are associated with that user. However, this will only be true with
+ *       certain components (such as Friends). Use with caution!
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose associated items are beind deleted.
+ * @param string $component_name Name of the associated component.
+ * @param string $component_action Name of the associated action.
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_delete_notifications_from_user( $user_id, $component_name, $component_action ) {
+	return BP_Notifications_Notification::delete( array(
+		'item_id'           => $user_id,
+		'component_name'    => $component_name,
+		'component_action'  => $component_action,
+	) );
+}
+
+/** Mark **********************************************************************/
+
+/**
+ * Mark notifications read/unread for a user by type.
+ *
+ * Used when clearing out notifications for a specific component when the user
+ * has visited that component.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose notifications are being deleted.
+ * @param string $component_name Name of the associated component.
+ * @param string $component_action Name of the associated action.
+ * @param int $is_new 0 for read, 1 for unread
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_mark_notifications_by_type( $user_id, $component_name, $component_action, $is_new = false ) {
+	return BP_Notifications_Notification::update(
+		array(
+			'is_new' => $is_new
+		),
+		array(
+			'user_id'          => $user_id,
+			'component_name'   => $component_name,
+			'component_action' => $component_action
+		)
+	);
+}
+
+/**
+ * Mark notifications read/unread for an item ID.
+ *
+ * Used when clearing out notifications for a specific component when the user
+ * has visited that component.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose notifications are being deleted.
+ * @param int $item_id ID of the associated item.
+ * @param string $component_name Name of the associated component.
+ * @param string $component_action Name of the associated action.
+ * @param int $secondary_item_id ID of the secondary associated item.
+ * @param int $is_new 0 for read, 1 for unread
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_mark_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false, $is_new = false ) {
+	return BP_Notifications_Notification::update(
+		array(
+			'is_new' => $is_new
+		),
+		array(
+			'user_id'           => $user_id,
+			'item_id'           => $item_id,
+			'secondary_item_id' => $secondary_item_id,
+			'component_name'    => $component_name,
+			'component_action'  => $component_action
+		)
+	);
+}
+
+/**
+ * Mark all notifications read/unread by type.
+ *
+ * Used when clearing out notifications for an entire component.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose notifications are being deleted.
+ * @param int $is_new 0 for read, 1 for unread
+ * @param string $component_name Name of the associated component.
+ * @param string $component_action Optional. Name of the associated action.
+ * @param int $secondary_item_id Optional. ID of the secondary associated item.
+ * @param int $is_new 0 for read, 1 for unread
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_mark_all_notifications_by_type( $item_id, $component_name, $component_action = false, $secondary_item_id = false, $is_new = false ) {
+	return BP_Notifications_Notification::update(
+		array(
+			'is_new' => $is_new
+		),
+		array(
+			'item_id'           => $item_id,
+			'secondary_item_id' => $secondary_item_id,
+			'component_name'    => $component_name,
+			'component_action'  => $component_action
+		)
+	);
+}
+
+/**
+ * Mark all notifications read/unread from a user.
+ *
+ * Used when clearing out all notifications for a user, when deleted or spammed.
+ *
+ * @todo This function assumes that items with the user_id in the item_id slot
+ *       are associated with that user. However, this will only be true with
+ *       certain components (such as Friends). Use with caution!
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose associated items are beind deleted.
+ * @param int $is_new 0 for read, 1 for unread
+ * @param string $component_name Name of the associated component.
+ * @param string $component_action Name of the associated action.
+ * @param int $is_new 0 for read, 1 for unread
+ * @return bool True on success, false on failure.
+ */
+function bp_notifications_mark_notifications_from_user( $user_id, $component_name, $component_action, $is_new = false ) {
+	return BP_Notifications_Notification::update(
+		array(
+			'is_new' => $is_new
+		),
+		array(
+			'item_id'          => $user_id,
+			'component_name'   => $component_name,
+			'component_action' => $component_action
+		)
+	);
+}
+
+/** Helpers *******************************************************************/
+
+/**
+ * Check if a user has access to a specific notification.
+ *
+ * Used before deleting a notification for a user.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user being checked.
+ * @param int $notification_id ID of the notification being checked.
+ * @return bool True if the notification belongs to the user, otherwise false.
+ */
+function bp_notifications_check_notification_access( $user_id, $notification_id ) {
+	return (bool) BP_Notifications_Notification::check_access( $user_id, $notification_id );
+}
+
+/**
+ * Get a count of unread notification items for a user.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param int $user_id ID of the user whose unread notifications are being
+ *        counted.
+ * @return int Unread notification count.
+ */
+function bp_notifications_get_unread_notification_count( $user_id = 0 ) {
+
+	// Default to displayed user if no ID is passed
+	if ( empty( $user_id ) ) {
+		$user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
+	}
+
+	// Get the notifications, and count them
+	$notifications = wp_cache_get( 'all_for_user_' . $user_id, 'bp_notifications' );
+	if ( false === $notifications ) {
+		$notifications = BP_Notifications_Notification::get( array(
+			'user_id' => $user_id,
+		) );
+		wp_cache_set( 'all_for_user_' . $user_id, $notifications, 'bp_notifications' );
+	}
+
+	$count = ! empty( $notifications ) ? count( $notifications ) : 0;
+
+	return apply_filters( 'bp_notifications_get_total_notification_count', $count );
+}
+
+/**
+ * Return an array of component names that are currently active and have
+ * registered Notifications callbacks.
+ *
+ * @since BuddyPress (1.9.1)
+ *
+ * @see http://buddypress.trac.wordpress.org/ticket/5300
+ */
+function bp_notifications_get_registered_components() {
+
+	// Load BuddyPress
+	$bp = buddypress();
+
+	// Setup return value
+	$component_names = array();
+
+	// Get the active components
+	$active_components = array_keys( $bp->active_components );
+
+	// Loop through components, look for callbacks, add to return value
+	foreach ( $active_components as $component ) {
+		if ( !empty( $bp->$component->notification_callback ) ) {
+			$component_names[] = $component;
+		}
+	}
+
+	// Return active components with registered notifications callbacks
+	return apply_filters( 'bp_notifications_get_registered_components', $component_names, $active_components );
+}
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-loader.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-loader.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab440697e01ff580fd8e3fb9ad6a90a56b719bbe
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-loader.php
@@ -0,0 +1,254 @@
+<?php
+
+/**
+ * BuddyPress Member Notifications Loader.
+ *
+ * Initializes the Notifications component.
+ *
+ * @package BuddyPress
+ * @subpackage NotificationsLoader
+ * @since BuddyPress (1.9.0)
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+class BP_Notifications_Component extends BP_Component {
+
+	/**
+	 * Start the notifications component creation process.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 */
+	public function __construct() {
+		parent::start(
+			'notifications',
+			__( 'Notifications', 'buddypress' ),
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 30
+			)
+		);
+	}
+
+	/**
+	 * Include notifications component files.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see BP_Component::includes() for a description of arguments.
+	 *
+	 * @param array $includes See BP_Component::includes() for a description.
+	 */
+	public function includes( $includes = array() ) {
+		$includes = array(
+			'actions',
+			'classes',
+			'screens',
+			'adminbar',
+			'buddybar',
+			'template',
+			'functions',
+			'cache',
+		);
+
+		parent::includes( $includes );
+	}
+
+	/**
+	 * Setup globals
+	 *
+	 * The BP_FRIENDS_SLUG constant is deprecated, and only used here for
+	 * backwards compatibility.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see BP_Component::setup_globals() for a description of arguments.
+	 *
+	 * @param array $args See BP_Component::setup_globals() for a description.
+	 */
+	public function setup_globals( $args = array() ) {
+		// Define a slug, if necessary
+		if ( !defined( 'BP_NOTIFICATIONS_SLUG' ) ) {
+			define( 'BP_NOTIFICATIONS_SLUG', $this->id );
+		}
+
+		// Global tables for the notifications component
+		$global_tables = array(
+			'table_name' => bp_core_get_table_prefix() . 'bp_notifications'
+		);
+
+		// All globals for the notifications component.
+		// Note that global_tables is included in this array.
+		$args = array(
+			'slug'          => BP_NOTIFICATIONS_SLUG,
+			'has_directory' => false,
+			'search_string' => __( 'Search Notifications...', 'buddypress' ),
+			'global_tables' => $global_tables,
+		);
+
+		parent::setup_globals( $args );
+	}
+
+	/**
+	 * Set up component navigation.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see BP_Component::setup_nav() for a description of arguments.
+	 *
+	 * @param array $main_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
+	 * @param array $sub_nav Optional. See BP_Component::setup_nav() for
+	 *        description.
+	 */
+	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
+
+		// Only grab count if we're on a user page and current user has access
+		if ( bp_is_user() && bp_user_has_access() ) {
+			$count    = bp_notifications_get_unread_notification_count( bp_displayed_user_id() );
+			$class    = ( 0 === $count ) ? 'no-count' : 'count';
+			$nav_name = sprintf( __( 'Notifications <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), number_format_i18n( $count ) );
+		} else {
+			$nav_name = __( 'Notifications', 'buddypress' );
+		}
+
+		// Add 'Notifications' to the main navigation
+		$main_nav = array(
+			'name'                    => $nav_name,
+			'slug'                    => $this->slug,
+			'position'                => 30,
+			'show_for_displayed_user' => bp_core_can_edit_settings(),
+			'screen_function'         => 'bp_notifications_screen_unread',
+			'default_subnav_slug'     => 'unread',
+			'item_css_id'             => $this->id,
+		);
+
+		// Determine user to use
+		if ( bp_displayed_user_domain() ) {
+			$user_domain = bp_displayed_user_domain();
+		} elseif ( bp_loggedin_user_domain() ) {
+			$user_domain = bp_loggedin_user_domain();
+		} else {
+			return;
+		}
+
+		$notifications_link = trailingslashit( $user_domain . bp_get_notifications_slug() );
+
+		// Add the subnav items to the notifications nav item
+		$sub_nav[] = array(
+			'name'            => __( 'Unread', 'buddypress' ),
+			'slug'            => 'unread',
+			'parent_url'      => $notifications_link,
+			'parent_slug'     => bp_get_notifications_slug(),
+			'screen_function' => 'bp_notifications_screen_unread',
+			'position'        => 10,
+			'item_css_id'     => 'notifications-my-notifications',
+			'user_has_access' => bp_core_can_edit_settings(),
+		);
+
+		$sub_nav[] = array(
+			'name'            => __( 'Read',   'buddypress' ),
+			'slug'            => 'read',
+			'parent_url'      => $notifications_link,
+			'parent_slug'     => bp_get_notifications_slug(),
+			'screen_function' => 'bp_notifications_screen_read',
+			'position'        => 20,
+			'user_has_access' => bp_core_can_edit_settings(),
+		);
+
+		parent::setup_nav( $main_nav, $sub_nav );
+	}
+
+	/**
+	 * Set up the component entries in the WordPress Admin Bar.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see BP_Component::setup_nav() for a description of the $wp_admin_nav
+	 *      parameter array.
+	 *
+	 * @param array $wp_admin_nav See BP_Component::setup_admin_bar() for a
+	 *        description.
+	 */
+	public function setup_admin_bar( $wp_admin_nav = array() ) {
+
+		// Menus for logged in user
+		if ( is_user_logged_in() ) {
+
+			// Setup the logged in user variables
+			$notifications_link = trailingslashit( bp_loggedin_user_domain() . $this->slug );
+
+			// Pending notification requests
+			$count = bp_notifications_get_unread_notification_count( bp_loggedin_user_id() );
+			if ( ! empty( $count ) ) {
+				$title  = sprintf( __( 'Notifications <span class="count">%s</span>', 'buddypress' ), number_format_i18n( $count ) );
+				$unread = sprintf( __( 'Unread <span class="count">%s</span>',        'buddypress' ), number_format_i18n( $count ) );
+			} else {
+				$title  = __( 'Notifications', 'buddypress' );
+				$unread = __( 'Unread',        'buddypress' );
+			}
+
+			// Add the "My Account" sub menus
+			$wp_admin_nav[] = array(
+				'parent' => buddypress()->my_account_menu_id,
+				'id'     => 'my-account-' . $this->id,
+				'title'  => $title,
+				'href'   => trailingslashit( $notifications_link ),
+			);
+
+			// Unread
+			$wp_admin_nav[] = array(
+				'parent' => 'my-account-' . $this->id,
+				'id'     => 'my-account-' . $this->id . '-unread',
+				'title'  => $unread,
+				'href'   => trailingslashit( $notifications_link ),
+			);
+
+			// Read
+			$wp_admin_nav[] = array(
+				'parent' => 'my-account-' . $this->id,
+				'id'     => 'my-account-' . $this->id . '-read',
+				'title'  => __( 'Read', 'buddypress' ),
+				'href'   => trailingslashit( $notifications_link . 'read' ),
+			);
+		}
+
+		parent::setup_admin_bar( $wp_admin_nav );
+	}
+
+	/**
+	 * Set up the title for pages and <title>.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 */
+	public function setup_title() {
+		$bp = buddypress();
+
+		// Adjust title
+		if ( bp_is_notifications_component() ) {
+			if ( bp_is_my_profile() ) {
+				$bp->bp_options_title = __( 'Notifications', 'buddypress' );
+			} else {
+				$bp->bp_options_avatar = bp_core_fetch_avatar( array(
+					'item_id' => bp_displayed_user_id(),
+					'type'    => 'thumb',
+					'alt'     => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() )
+				) );
+				$bp->bp_options_title = bp_get_displayed_user_fullname();
+			}
+		}
+
+		parent::setup_title();
+	}
+}
+
+/**
+ * Bootstrap the Notifications component.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_setup_notifications() {
+	buddypress()->notifications = new BP_Notifications_Component();
+}
+add_action( 'bp_setup_components', 'bp_setup_notifications', 6 );
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-screens.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-screens.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb65c88f50fcb49b5c93c9f49584360453d671fb
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-screens.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * BuddyPress Notifications Screen Functions.
+ *
+ * Screen functions are the controllers of BuddyPress. They will execute when
+ * their specific URL is caught. They will first save or manipulate data using
+ * business functions, then pass on the user to a template file.
+ *
+ * @package BuddyPress
+ * @subpackage NotificationsScreens
+ */
+
+// Exit if accessed directly
+if ( ! defined( 'ABSPATH' ) ) exit;
+
+/**
+ * Catch and route the 'unread' notifications screen.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_screen_unread() {
+	do_action( 'bp_notifications_screen_unread' );
+
+	bp_core_load_template( apply_filters( 'bp_notifications_template_unread', 'members/single/home' ) );
+}
+
+/**
+ * Catch and route the 'read' notifications screen.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_screen_read() {
+	do_action( 'bp_notifications_screen_read' );
+
+	bp_core_load_template( apply_filters( 'bp_notifications_template_read', 'members/single/home' ) );
+}
+
+/**
+ * Catch and route the 'settings' notifications screen.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_screen_settings() {
+
+}
diff --git a/wp-content/plugins/buddypress/bp-notifications/bp-notifications-template.php b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-template.php
new file mode 100644
index 0000000000000000000000000000000000000000..47bcdcac8e2d64a36a7c2023799d4134e9703bcc
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-notifications/bp-notifications-template.php
@@ -0,0 +1,953 @@
+<?php
+
+/**
+ * BuddyPress Notifications Template Functions
+ *
+ * @package BuddyPress
+ * @subpackage TonificationsTemplate
+ */
+
+// Exit if accessed directly
+if ( !defined( 'ABSPATH' ) ) exit;
+
+/**
+ * Output the notifications component slug.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_slug() {
+	echo bp_get_notifications_slug();
+}
+	/**
+	 * Return the notifications component slug.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string Slug of the Notifications component.
+	 */
+	function bp_get_notifications_slug() {
+		return apply_filters( 'bp_get_notifications_slug', buddypress()->notifications->slug );
+	}
+
+/**
+ * Output the notifications permalink.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_permalink() {
+	echo bp_get_notifications_permalink();
+}
+	/**
+	 * Return the notifications permalink.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string Notifications permalink
+	 */
+	function bp_get_notifications_permalink() {
+		$retval = trailingslashit( bp_loggedin_user_domain() . bp_get_notifications_slug() );
+		return apply_filters( 'bp_get_notifications_permalink', $retval );
+	}
+
+/**
+ * Output the unread notifications permalink.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_unread_permalink() {
+	echo bp_get_notifications_unread_permalink();
+}
+	/**
+	 * Return the unread notifications permalink.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string Unread notifications permalink
+	 */
+	function bp_get_notifications_unread_permalink() {
+		$retval = trailingslashit( bp_loggedin_user_domain() . bp_get_notifications_slug() . '/unread' );
+		return apply_filters( 'bp_get_notifications_unread_permalink', $retval );
+	}
+
+/**
+ * Output the read notifications permalink.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_read_permalink() {
+	echo bp_get_notifications_read_permalink();
+}
+	/**
+	 * Return the read notifications permalink.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string Read notifications permalink
+	 */
+	function bp_get_notifications_read_permalink() {
+		$retval = trailingslashit( bp_loggedin_user_domain() . bp_get_notifications_slug() . '/read' );
+		return apply_filters( 'bp_get_notifications_unread_permalink', $retval );
+	}
+
+/** Main Loop *****************************************************************/
+
+/**
+ * The main notifications template loop class.
+ *
+ * Responsible for loading a group of notifications into a loop for display.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+class BP_Notifications_Template {
+
+	/**
+	 * The loop iterator.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var int
+	 */
+	public $current_notification = -1;
+
+	/**
+	 * The number of notifications returned by the paged query.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var int
+	 */
+	public $current_notification_count;
+
+	/**
+	 * Total number of notifications matching the query.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var int
+	 */
+	public $total_notification_count;
+
+	/**
+	 * Array of notifications located by the query.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var array
+	 */
+	public $notifications;
+
+	/**
+	 * The notification object currently being iterated on.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var object
+	 */
+	public $notification;
+
+	/**
+	 * A flag for whether the loop is currently being iterated.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var bool
+	 */
+	public $in_the_loop;
+
+	/**
+	 * The ID of the user to whom the displayed notifications belong.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var int
+	 */
+	public $user_id;
+
+	/**
+	 * The page number being requested.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var int
+	 */
+	public $pag_page;
+
+	/**
+	 * The number of items to display per page of results.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var int
+	 */
+	public $pag_num;
+
+	/**
+	 * An HTML string containing pagination links.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var string
+	 */
+	public $pag_links;
+
+	/**
+	 * A string to match against.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var string
+	 */
+	public $search_terms;
+
+	/**
+	 * A database column to order the results by.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var string
+	 */
+	public $order_by;
+
+	/**
+	 * The direction to sort the results (ASC or DESC)
+	 *
+	 * @since BuddyPress (1.9.0)
+	 * @access public
+	 * @var string
+	 */
+	public $sort_order;
+
+	/**
+	 * Constructor method.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param array $args {
+	 *     @type int $user_id ID of the user to whom the displayed
+	 *           notifications belong.
+	 *     @type bool $is_new Whether to limit the query to unread
+	 *           notifications. Default: true.
+	 *     @type int $page Number of the page of results to return.
+	 *           Will be overridden by URL parameter. Default: 1.
+	 *     @type int $per_page Number of results to return per page.
+	 *           Will be overridden by URL parameter. Default: 25.
+	 *     @type int $max Optional. Max results to display.
+	 *     @type string $search_terms Optional. Term to match against
+	 *           component_name and component_action.
+	 *     @type string $page_arg URL argument to use for pagination.
+	 *           Default: 'npage'.
+	 * }
+	 */
+	public function __construct( $args = array() ) {
+
+		// Parse arguments
+		$r = wp_parse_args( $args, array(
+			'user_id'      => 0,
+			'is_new'       => true,
+			'page'         => 1,
+			'per_page'     => 25,
+			'order_by'     => 'date_notified',
+			'sort_order'   => 'DESC',
+			'max'          => null,
+			'search_terms' => '',
+			'page_arg'     => 'npage',
+		) );
+
+		// Overrides
+
+		// Set which pagination page
+		if ( isset( $_GET[ $r['page_arg'] ] ) ) {
+			$pag_page = intval( $_GET[ $r['page_arg'] ] );
+		} else {
+			$pag_page = $r['page'];
+		}
+
+		// Set the number to show per page
+		if ( isset( $_GET['num'] ) ) {
+			$pag_num = intval( $_GET['num'] );
+		} else {
+			$pag_num = intval( $r['per_page'] );
+		}
+
+		// Sort order direction
+		$orders = array( 'ASC', 'DESC' );
+		if ( ! empty( $_GET['sort_order'] ) && in_array( $_GET['sort_order'], $orders ) ) {
+			$sort_order = $_GET['sort_order'];
+		} else {
+			$sort_order = in_array( $r['sort_order'], $orders ) ? $r['sort_order'] : 'DESC';
+		}
+
+		// Setup variables
+		$this->pag_page     = $pag_page;
+		$this->pag_num      = $pag_num;
+		$this->user_id      = $r['user_id'];
+		$this->is_new       = $r['is_new'];
+		$this->search_terms = $r['search_terms'];
+		$this->page_arg     = $r['page_arg'];
+		$this->order_by     = $r['order_by'];
+		$this->sort_order   = $sort_order;
+
+		// Get the notifications
+		$notifications      = BP_Notifications_Notification::get_current_notifications_for_user( array(
+			'user_id'      => $this->user_id,
+			'is_new'       => $this->is_new,
+			'page'         => $this->pag_page,
+			'per_page'     => $this->pag_num,
+			'search_terms' => $this->search_terms,
+			'order_by'     => $this->order_by,
+			'sort_order'   => $this->sort_order,
+		) );
+
+		// Setup the notifications to loop through
+		$this->notifications            = $notifications['notifications'];
+		$this->total_notification_count = $notifications['total'];
+
+		if ( empty( $this->notifications ) ) {
+			$this->notification_count       = 0;
+			$this->total_notification_count = 0;
+
+		} else {
+			if ( ! empty( $max ) ) {
+				if ( $max >= count( $this->notifications ) ) {
+					$this->notification_count = count( $this->notifications );
+				} else {
+					$this->notification_count = (int) $max;
+				}
+			} else {
+				$this->notification_count = count( $this->notifications );
+			}
+		}
+
+		if ( (int) $this->total_notification_count && (int) $this->pag_num ) {
+			$this->pag_links = paginate_links( array(
+				'base'      => add_query_arg( $this->page_arg, '%#%' ),
+				'format'    => '',
+				'total'     => ceil( (int) $this->total_notification_count / (int) $this->pag_num ),
+				'current'   => $this->pag_page,
+				'prev_text' => _x( '&larr;', 'Notifications pagination previous text', 'buddypress' ),
+				'next_text' => _x( '&rarr;', 'Notifications pagination next text',     'buddypress' ),
+				'mid_size'  => 1,
+			) );
+
+			// Remove first page from pagination
+			$this->pag_links = str_replace( '?'      . $r['page_arg'] . '=1', '', $this->pag_links );
+			$this->pag_links = str_replace( '&#038;' . $r['page_arg'] . '=1', '', $this->pag_links );
+		}
+	}
+
+	/**
+	 * Whether there are notifications available in the loop.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see bp_has_notifications()
+	 *
+	 * @return bool True if there are items in the loop, otherwise false.
+	 */
+	public function has_notifications() {
+		if ( $this->notification_count ) {
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Set up the next notification and iterate index.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return object The next notification to iterate over.
+	 */
+	public function next_notification() {
+
+		$this->current_notification++;
+
+		$this->notification = $this->notifications[ $this->current_notification ];
+
+		return $this->notification;
+	}
+
+	/**
+	 * Rewind the blogs and reset blog index.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 */
+	public function rewind_notifications() {
+
+		$this->current_notification = -1;
+
+		if ( $this->notification_count > 0 ) {
+			$this->notification = $this->notifications[0];
+		}
+	}
+
+	/**
+	 * Whether there are notifications left in the loop to iterate over.
+	 *
+	 * This method is used by {@link bp_notifications()} as part of the
+	 * while loop that controls iteration inside the notifications loop, eg:
+	 *     while ( bp_notifications() ) { ...
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see bp_notifications()
+	 *
+	 * @return bool True if there are more notifications to show,
+	 *         otherwise false.
+	 */
+	public function notifications() {
+
+		if ( $this->current_notification + 1 < $this->notification_count ) {
+			return true;
+
+		} elseif ( $this->current_notification + 1 == $this->notification_count ) {
+			do_action( 'notifications_loop_end');
+
+			$this->rewind_notifications();
+		}
+
+		$this->in_the_loop = false;
+		return false;
+	}
+
+	/**
+	 * Set up the current notification inside the loop.
+	 *
+	 * Used by {@link bp_the_notification()} to set up the current
+	 * notification data while looping, so that template tags used during
+	 * that iteration make reference to the current notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @see bp_the_notification()
+	 */
+	public function the_notification() {
+		$this->in_the_loop  = true;
+		$this->notification = $this->next_notification();
+
+		// loop has just started
+		if ( 0 === $this->current_notification ) {
+			do_action( 'notifications_loop_start' );
+		}
+	}
+}
+
+/** The Loop ******************************************************************/
+
+/**
+ * Initialize the notifications loop.
+ *
+ * Based on the $args passed, bp_has_notifications() populates
+ * buddypress()->notifications->query_loop global, enabling the use of BP
+ * templates and template functions to display a list of notifications.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @param array $args {
+ *     Arguments for limiting the contents of the notifications loop. Can be
+ *     passed as an associative array, or as a URL query string.
+ *     @type int $user_id ID of the user to whom notifications belong. Default:
+ *           ID of the logged-in user.
+ *     @type bool $is_new Whether to limit query to unread notifications.
+ *           Default: when viewing the 'unread' tab, defaults to true; when
+ *           viewing the 'read' tab, defaults to false.
+ *     @type int $page The page of notifications being fetched. Default: 1.
+ *     @type int $per_page Number of items to display on a page. Default: 25.
+ *     @type int $max Optional. Max items to display. Default: false.
+ *     @type string $search_terms Optional. Term to match against
+ *           component_name and component_action.
+ *     @type string $page_arg URL argument to use for pagination.
+ *           Default: 'npage'.
+ * }
+ */
+function bp_has_notifications( $args = '' ) {
+
+	// Get the default is_new argument
+	if ( bp_is_current_action( 'unread' ) ) {
+		$is_new = 1;
+	} elseif ( bp_is_current_action( 'read' ) ) {
+		$is_new = 0;
+	}
+
+	// Get the user ID
+	if ( bp_displayed_user_id() ) {
+		$user_id = bp_displayed_user_id();
+	} else {
+		$user_id = bp_loggedin_user_id();
+	}
+
+	// Parse the args
+	$r = bp_parse_args( $args, array(
+		'user_id'      => $user_id,
+		'is_new'       => $is_new,
+		'page'         => 1,
+		'per_page'     => 25,
+		'max'          => false,
+		'search_terms' => isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '',
+		'page_arg'     => 'npage',
+	), 'has_notifications' );
+
+	// Get the notifications
+	$query_loop = new BP_Notifications_Template( $r );
+
+	// Setup the global query loop
+	buddypress()->notifications->query_loop = $query_loop;
+
+	return apply_filters( 'bp_has_notifications', $query_loop->has_notifications(), $query_loop );
+}
+
+/**
+ * Get the notifications returned by the template loop.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return array List of notifications.
+ */
+function bp_the_notifications() {
+	return buddypress()->notifications->query_loop->notifications();
+}
+
+/**
+ * Get the current notification object in the loop.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @return object The current notification within the loop.
+ */
+function bp_the_notification() {
+	return buddypress()->notifications->query_loop->the_notification();
+}
+
+/** Loop Output ***************************************************************/
+
+/**
+ * Output the ID of the notification currently being iterated on.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_id() {
+	echo bp_get_the_notification_id();
+}
+	/**
+	 * Return the ID of the notification currently being iterated on.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return int ID of the current notification.
+	 */
+	function bp_get_the_notification_id() {
+		return apply_filters( 'bp_get_the_notification_id', buddypress()->notifications->query_loop->notification->id );
+	}
+
+/**
+ * Output the associated item ID of the notification currently being iterated on.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_item_id() {
+	echo bp_get_the_notification_item_id();
+}
+	/**
+	 * Return the associated item ID of the notification currently being iterated on.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return int ID of the item associated with the current notification.
+	 */
+	function bp_get_the_notification_item_id() {
+		return apply_filters( 'bp_get_the_notification_item_id', buddypress()->notifications->query_loop->notification->item_id );
+	}
+
+/**
+ * Output the secondary associated item ID of the notification currently being iterated on.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_secondary_item_id() {
+	echo bp_get_the_notification_secondary_item_id();
+}
+	/**
+	 * Return the secondary associated item ID of the notification currently being iterated on.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return int ID of the secondary item associated with the current notification.
+	 */
+	function bp_get_the_notification_secondary_item_id() {
+		return apply_filters( 'bp_get_the_notification_secondary_item_id', buddypress()->notifications->query_loop->notification->secondary_item_id );
+	}
+
+/**
+ * Output the name of the component associated with the notification currently being iterated on.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_component_name() {
+	echo bp_get_the_notification_component_name();
+}
+	/**
+	 * Return the name of the component associated with the notification currently being iterated on.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return int Name of the component associated with the current notification.
+	 */
+	function bp_get_the_notification_component_name() {
+		return apply_filters( 'bp_get_the_notification_component_name', buddypress()->notifications->query_loop->notification->component_name );
+	}
+
+/**
+ * Output the name of the action associated with the notification currently being iterated on.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_component_action() {
+	echo bp_get_the_notification_component_action();
+}
+	/**
+	 * Return the name of the action associated with the notification currently being iterated on.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return int Name of the action associated with the current notification.
+	 */
+	function bp_get_the_notification_component_action() {
+		return apply_filters( 'bp_get_the_notification_component_action', buddypress()->notifications->query_loop->notification->component_action );
+	}
+
+/**
+ * Output the timestamp of the current notification.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_date_notified() {
+	echo bp_get_the_notification_date_notified();
+}
+	/**
+	 * Return the timestamp of the current notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string Timestamp of the current notification.
+	 */
+	function bp_get_the_notification_date_notified() {
+		return apply_filters( 'bp_get_the_notification_date_notified', buddypress()->notifications->query_loop->notification->date_notified );
+	}
+
+/**
+ * Output the timestamp of the current notification.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_time_since() {
+	echo bp_get_the_notification_time_since();
+}
+	/**
+	 * Return the timestamp of the current notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string Timestamp of the current notification.
+	 */
+	function bp_get_the_notification_time_since() {
+
+		// Get the notified date
+		$date_notified = bp_get_the_notification_date_notified();
+
+		// Notified date has legitimate data
+		if ( '0000-00-00 00:00:00' !== $date_notified ) {
+			$retval = bp_core_time_since( $date_notified );
+
+		// Notified date is empty, so return a fun string
+		} else {
+			$retval = __( 'Date not found', 'buddypress' );
+		}
+
+		return apply_filters( 'bp_get_the_notification_time_since', $retval );
+	}
+
+/**
+ * Output full-text description for a specific notification.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_description() {
+	echo bp_get_the_notification_description();
+}
+
+	/**
+	 * Get full-text description for a specific notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string
+	 */
+	function bp_get_the_notification_description() {
+
+		// Setup local variables
+		$description  = '';
+		$bp           = buddypress();
+		$notification = $bp->notifications->query_loop->notification;
+
+		// Callback function exists
+		if ( isset( $bp->{ $notification->component_name }->notification_callback ) && is_callable( $bp->{ $notification->component_name }->notification_callback ) ) {
+			$description = call_user_func( $bp->{ $notification->component_name }->notification_callback, $notification->component_action, $notification->item_id, $notification->secondary_item_id, 1 );
+
+		// @deprecated format_notification_function - 1.5
+		} elseif ( isset( $bp->{ $notification->component_name }->format_notification_function ) && function_exists( $bp->{ $notification->component_name }->format_notification_function ) ) {
+			$description = call_user_func( $bp->{ $notification->component_name }->format_notification_function, $notification->component_action, $notification->item_id, $notification->secondary_item_id, 1 );
+
+		// Allow non BuddyPress components to hook in
+		} else {
+			$description = apply_filters_ref_array( 'bp_notifications_get_notifications_for_user', array( $notification->component_action, $notification->item_id, $notification->secondary_item_id, 1 ) );
+		}
+
+		// Filter and return
+		return apply_filters( 'bp_get_the_notification_description', $description );
+	}
+
+/**
+ * Output the mark read link for the current notification.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @uses bp_get_the_notification_mark_read_link()
+ */
+function bp_the_notification_mark_read_link() {
+	echo bp_get_the_notification_mark_read_link();
+}
+	/**
+	 * Return the mark read link for the current notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 */
+	function bp_get_the_notification_mark_read_link() {
+
+		// Get the URL with nonce, action, and id
+		$url = wp_nonce_url( add_query_arg( array( 'action' => 'read', 'notification_id' => bp_get_the_notification_id() ), bp_get_notifications_unread_permalink() ), 'bp_notification_mark_read_' . bp_get_the_notification_id() );
+
+		// Start the output buffer
+		ob_start(); ?>
+
+		<a href="<?php echo esc_url( $url ); ?>" class="mark-read primary"><?php _e( 'Read', 'buddypress' ); ?></a>
+
+		<?php $retval = ob_get_clean();
+
+		return apply_filters( 'bp_get_the_notification_mark_read_link', $retval );
+	}
+
+/**
+ * Output the mark read link for the current notification.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @uses bp_get_the_notification_mark_unread_link()
+ */
+function bp_the_notification_mark_unread_link() {
+	echo bp_get_the_notification_mark_unread_link();
+}
+	/**
+	 * Return the mark read link for the current notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 */
+	function bp_get_the_notification_mark_unread_link() {
+
+		// Get the URL with nonce, action, and id
+		$url = wp_nonce_url( add_query_arg( array( 'action' => 'unread', 'notification_id' => bp_get_the_notification_id() ), bp_get_notifications_read_permalink() ), 'bp_notification_mark_unread_' . bp_get_the_notification_id() );
+
+		// Start the output buffer
+		ob_start(); ?>
+
+		<a href="<?php echo esc_url( $url ); ?>" class="mark-unread primary"><?php _e( 'Unread', 'buddypress' ); ?></a>
+
+		<?php $retval = ob_get_clean();
+
+		return apply_filters( 'bp_get_the_notification_mark_unread_link', $retval );
+	}
+
+/**
+ * Output the mark link for the current notification.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @uses bp_get_the_notification_mark_unread_link()
+ */
+function bp_the_notification_mark_link() {
+	echo bp_get_the_notification_mark_link();
+}
+	/**
+	 * Return the mark link for the current notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 */
+	function bp_get_the_notification_mark_link() {
+
+		if ( bp_is_current_action( 'read' ) ) {
+			$retval = bp_get_the_notification_mark_unread_link();
+		} else {
+			$retval = bp_get_the_notification_mark_read_link();
+		}
+
+		return apply_filters( 'bp_get_the_notification_mark_link', $retval );
+	}
+
+/**
+ * Output the delete link for the current notification.
+ *
+ * @since BuddyPress (1.9.0)
+ *
+ * @uses bp_get_the_notification_delete_link()
+ */
+function bp_the_notification_delete_link() {
+	echo bp_get_the_notification_delete_link();
+}
+	/**
+	 * Return the delete link for the current notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 */
+	function bp_get_the_notification_delete_link() {
+
+		// URL to add nonce to
+		if ( bp_is_current_action( 'unread' ) ) {
+			$link = bp_get_notifications_unread_permalink();
+		} elseif ( bp_is_current_action( 'read' ) ) {
+			$link = bp_get_notifications_read_permalink();
+		}
+
+		// Get the URL with nonce, action, and id
+		$url = wp_nonce_url( add_query_arg( array( 'action' => 'delete', 'notification_id' => bp_get_the_notification_id() ), $link ), 'bp_notification_delete_' . bp_get_the_notification_id() );
+
+		// Start the output buffer
+		ob_start(); ?>
+
+		<a href="<?php echo esc_url( $url ); ?>" class="delete secondary confirm"><?php _e( 'Delete', 'buddypress' ); ?></a>
+
+		<?php $retval = ob_get_clean();
+
+		return apply_filters( 'bp_get_the_notification_delete_link', $retval );
+	}
+
+/**
+ * Output the action links for the current notification.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_the_notification_action_links( $args = '' ) {
+	echo bp_get_the_notification_action_links( $args );
+}
+	/**
+	 * Return the action links for the current notification.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @param array $args {
+	 *     @type string $before HTML before the links
+	 *     @type string $after HTML after the links
+	 *     @type string $sep HTML between the links
+	 *     @type array $links Array of links to implode by 'sep'
+	 * }
+	 *
+	 * @return string HTML links for actions to take on single notifications.
+	 */
+	function bp_get_the_notification_action_links( $args = '' ) {
+
+		// Parse
+		$r = wp_parse_args( $args, array(
+			'before' => '',
+			'after'  => '',
+			'sep'    => ' | ',
+			'links'  => array(
+				bp_get_the_notification_mark_link(),
+				bp_get_the_notification_delete_link()
+			)
+		) );
+
+		// Build the links
+		$retval = $r['before'] . implode( $r['links'], $r['sep'] ) . $r['after'];
+
+		return apply_filters( 'bp_get_the_notification_action_links', $retval );
+	}
+
+/**
+ * Output the pagination count for the current notification loop.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_pagination_count() {
+	echo bp_get_notifications_pagination_count();
+}
+	/**
+	 * Return the pagination count for the current notification loop.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string HTML for the pagination count.
+	 */
+	function bp_get_notifications_pagination_count() {
+		$query_loop = buddypress()->notifications->query_loop;
+		$start_num  = intval( ( $query_loop->pag_page - 1 ) * $query_loop->pag_num ) + 1;
+		$from_num   = bp_core_number_format( $start_num );
+		$to_num     = bp_core_number_format( ( $start_num + ( $query_loop->pag_num - 1 ) > $query_loop->total_notification_count ) ? $query_loop->total_notification_count : $start_num + ( $query_loop->pag_num - 1 ) );
+		$total      = bp_core_number_format( $query_loop->total_notification_count );
+		$pag        = sprintf( _n( 'Viewing %1$s to %2$s (of %3$s notification)', 'Viewing %1$s to %2$s (of %3$s notifications)', $total, 'buddypress' ), $from_num, $to_num, $total );
+
+		return apply_filters( 'bp_notifications_pagination_count', $pag );
+	}
+
+/**
+ * Output the pagination links for the current notification loop.
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_pagination_links() {
+	echo bp_get_notifications_pagination_links();
+}
+	/**
+	 * Return the pagination links for the current notification loop.
+	 *
+	 * @since BuddyPress (1.9.0)
+	 *
+	 * @return string HTML for the pagination links.
+	 */
+	function bp_get_notifications_pagination_links() {
+		return apply_filters( 'bp_get_notifications_pagination_links', buddypress()->notifications->query_loop->pag_links );
+	}
+
+/** Form Helpers **************************************************************/
+
+/**
+ * Output the form for changing the sort order of notifications
+ *
+ * @since BuddyPress (1.9.0)
+ */
+function bp_notifications_sort_order_form() {
+
+	// Setup local variables
+	$orders   = array( 'DESC', 'ASC' );
+	$selected = 'DESC';
+
+	// Check for a custom sort_order
+	if ( !empty( $_REQUEST['sort_order'] ) ) {
+		if ( in_array( $_REQUEST['sort_order'], $orders ) ) {
+			$selected = $_REQUEST['sort_order'];
+		}
+	} ?>
+
+	<form action="" method="get" id="notifications-sort-order">
+		<label for="notifications-friends"><?php esc_html_e( 'Order By:', 'buddypress' ); ?></label>
+
+		<select id="notifications-sort-order-list" name="sort_order" onchange="this.form.submit();">
+			<option value="DESC" <?php selected( $selected, 'DESC' ); ?>><?php _e( 'Newest First', 'buddypress' ); ?></option>
+			<option value="ASC"  <?php selected( $selected, 'ASC'  ); ?>><?php _e( 'Oldest First', 'buddypress' ); ?></option>
+		</select>
+
+		<noscript>
+			<input id="submit" type="submit" name="form-submit" class="submit" value="<?php esc_attr_e( 'Go', 'buddypress' ); ?>" />
+		</noscript>
+	</form>
+
+<?php
+}
diff --git a/wp-content/plugins/buddypress/bp-settings/bp-settings-actions.php b/wp-content/plugins/buddypress/bp-settings/bp-settings-actions.php
index 8cca694336ec5d7a96dd66a91e173356709ece7d..d3e06f92b40edcd02e518bcf95f677288fd5062c 100644
--- a/wp-content/plugins/buddypress/bp-settings/bp-settings-actions.php
+++ b/wp-content/plugins/buddypress/bp-settings/bp-settings-actions.php
@@ -141,8 +141,10 @@ function bp_settings_action_general() {
 			}
 		}
 
-		// Make sure these changes are in $bp for the current page load
+		// Clear cached data, so that the changed settings take effect
+		// on the current page load
 		if ( ( false === $email_error ) && ( false === $pass_error ) && ( wp_update_user( $update_user ) ) ) {
+			wp_cache_delete( 'bp_core_userdata_' . bp_displayed_user_id(), 'bp' );
 			$bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
 		}
 
@@ -278,6 +280,12 @@ function bp_settings_action_capabilities() {
 		return;
 	}
 
+	// Only super admins can currently spam users (but they can't spam
+	// themselves)
+	if ( ! is_super_admin() || bp_is_my_profile() ) {
+		return;
+	}
+
 	// Nonce check
 	check_admin_referer( 'capabilities' );
 
diff --git a/wp-content/plugins/buddypress/bp-settings/bp-settings-loader.php b/wp-content/plugins/buddypress/bp-settings/bp-settings-loader.php
index 68d50880955257f1179f7ccfadc43dda1b807a57..8d97f5af7effac4115924f708935acbc43225bb2 100644
--- a/wp-content/plugins/buddypress/bp-settings/bp-settings-loader.php
+++ b/wp-content/plugins/buddypress/bp-settings/bp-settings-loader.php
@@ -21,7 +21,10 @@ class BP_Settings_Component extends BP_Component {
 		parent::start(
 			'settings',
 			__( 'Settings', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 100
+			)
 		);
 	}
 
@@ -30,7 +33,7 @@ class BP_Settings_Component extends BP_Component {
 	 *
 	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
-	public function includes() {
+	public function includes( $includes = array() ) {
 		parent::includes( array(
 			'actions',
 			'screens',
@@ -47,7 +50,7 @@ class BP_Settings_Component extends BP_Component {
 	 *
 	 * @since BuddyPress (1.5)
 	 */
-	public function setup_globals() {
+	public function setup_globals( $args = array() ) {
 
 		// Define a slug, if necessary
 		if ( !defined( 'BP_SETTINGS_SLUG' ) )
@@ -63,10 +66,7 @@ class BP_Settings_Component extends BP_Component {
 	/**
 	 * Setup BuddyBar navigation
 	 */
-	public function setup_nav() {
-
-		// Define local variable
-		$sub_nav = array();
+	public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
 
 		// Add the settings navigation item
 		$main_nav = array(
@@ -100,9 +100,10 @@ class BP_Settings_Component extends BP_Component {
 			'user_has_access' => bp_core_can_edit_settings()
 		);
 
-		// Add Notifications nav item
+		// Add Email nav item. Formerly called 'Notifications', we
+		// retain the old slug and function names for backward compat
 		$sub_nav[] = array(
-			'name'            => __( 'Notifications', 'buddypress' ),
+			'name'            => __( 'Email', 'buddypress' ),
 			'slug'            => 'notifications',
 			'parent_url'      => $settings_link,
 			'parent_slug'     => $this->slug,
@@ -143,14 +144,11 @@ class BP_Settings_Component extends BP_Component {
 	/**
 	 * Set up the Toolbar
 	 */
-	public function setup_admin_bar() {
+	public function setup_admin_bar( $wp_admin_nav = array() ) {
 
 		// The instance
 		$bp = buddypress();
 
-		// Prevent debug notices
-		$wp_admin_nav = array();
-
 		// Menus for logged in user
 		if ( is_user_logged_in() ) {
 
@@ -178,7 +176,7 @@ class BP_Settings_Component extends BP_Component {
 			$wp_admin_nav[] = array(
 				'parent' => 'my-account-' . $this->id,
 				'id'     => 'my-account-' . $this->id . '-notifications',
-				'title'  => __( 'Notifications', 'buddypress' ),
+				'title'  => __( 'Email', 'buddypress' ),
 				'href'   => trailingslashit( $settings_link . 'notifications' )
 			);
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress-functions.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress-functions.php
index 07fd408836de20cf22f73f13b3a7c96f60e21dcb..bca42bba68fbcdf6755c4074d7b485b005d0df94 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress-functions.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress-functions.php
@@ -111,6 +111,8 @@ class BP_Legacy extends BP_Theme_Compat {
 				add_action( 'bp_group_header_actions',     'bp_group_join_button',           5 );
 				add_action( 'bp_group_header_actions',     'bp_group_new_topic_button',      20 );
 				add_action( 'bp_directory_groups_actions', 'bp_group_join_button' );
+				add_filter( 'bp_groups_directory_header',  'bp_legacy_theme_group_create_button' );
+				add_filter( 'bp_blogs_directory_header',   'bp_legacy_theme_blog_create_button' );
 			}
 
 			// Blog button
@@ -121,7 +123,9 @@ class BP_Legacy extends BP_Theme_Compat {
 
 		/** Notices ***********************************************************/
 
-		if ( bp_is_active( 'messages' ) ) {
+		// Only hook the 'sitewide_notices' overlay if the Sitewide
+		// Notices widget is not in use (to avoid duplicate content).
+		if ( bp_is_active( 'messages' ) && ! is_active_widget( false, false, 'bp_messages_sitewide_notices_widget', true ) ) {
 			add_action( 'wp_footer', array( $this, 'sitewide_notices' ), 9999 );
 		}
 
@@ -135,6 +139,8 @@ class BP_Legacy extends BP_Theme_Compat {
 			'groups_filter'   => 'bp_legacy_theme_object_template_loader',
 			'members_filter'  => 'bp_legacy_theme_object_template_loader',
 			'messages_filter' => 'bp_legacy_theme_messages_template_loader',
+			'invite_filter'   => 'bp_legacy_theme_invite_template_loader',
+			'requests_filter' => 'bp_legacy_theme_requests_template_loader',
 
 			// Friends
 			'accept_friendship' => 'bp_legacy_theme_ajax_accept_friendship',
@@ -221,24 +227,26 @@ class BP_Legacy extends BP_Theme_Compat {
 		// Enqueue the global JS, if found - AJAX will not work
 		// without it
 		if ( isset( $asset['location'], $asset['handle'] ) ) {
-			wp_enqueue_script( $asset['handle'], $asset['location'], array( 'jquery' ), $this->version );
+			wp_enqueue_script( $asset['handle'], $asset['location'], bp_core_get_js_dependencies(), $this->version );
 		}
 
-		// Add words that we need to use in JS to the end of the page so they can be translated and still used.
-		$params = array(
-			'my_favs'           => __( 'My Favorites', 'buddypress' ),
-			'accepted'          => __( 'Accepted', 'buddypress' ),
-			'rejected'          => __( 'Rejected', 'buddypress' ),
-			'show_all_comments' => __( 'Show all comments for this thread', 'buddypress' ),
-			'show_x_comments'   => __( 'Show all %d comments', 'buddypress' ),
-			'show_all'          => __( 'Show all', 'buddypress' ),
-			'comments'          => __( 'comments', 'buddypress' ),
-			'close'             => __( 'Close', 'buddypress' ),
-			'view'              => __( 'View', 'buddypress' ),
-			'mark_as_fav'	    => __( 'Favorite', 'buddypress' ),
-			'remove_fav'	    => __( 'Remove Favorite', 'buddypress' ),
-			'unsaved_changes'   => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
-		);
+		// Add words that we need to use in JS to the end of the page
+		// so they can be translated and still used.
+		$params = apply_filters( 'bp_core_get_js_strings', array(
+			'accepted'            => __( 'Accepted', 'buddypress' ),
+			'close'               => __( 'Close', 'buddypress' ),
+			'comments'            => __( 'comments', 'buddypress' ),
+			'leave_group_confirm' => __( 'Are you sure you want to leave this group?', 'buddypress' ),
+			'mark_as_fav'	      => __( 'Favorite', 'buddypress' ),
+			'my_favs'             => __( 'My Favorites', 'buddypress' ),
+			'rejected'            => __( 'Rejected', 'buddypress' ),
+			'remove_fav'	      => __( 'Remove Favorite', 'buddypress' ),
+			'show_all'            => __( 'Show all', 'buddypress' ),
+			'show_all_comments'   => __( 'Show all comments for this thread', 'buddypress' ),
+			'show_x_comments'     => __( 'Show all %d comments', 'buddypress' ),
+			'unsaved_changes'     => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
+			'view'                => __( 'View', 'buddypress' ),
+		) );
 		wp_localize_script( $asset['handle'], 'BP_DTheme', $params );
 
 		// Maybe enqueue comment reply JS
@@ -329,7 +337,7 @@ class BP_Legacy extends BP_Theme_Compat {
 	public function head_scripts() {
 	?>
 
-		<script type="text/javascript" charset="utf-8">
+		<script type="text/javascript">
 			/* <![CDATA[ */
 			var ajaxurl = '<?php echo bp_core_ajax_url(); ?>';
 			/* ]]> */
@@ -415,6 +423,35 @@ class BP_Legacy extends BP_Theme_Compat {
 new BP_Legacy();
 endif;
 
+/**
+ * Add the Create a Group button to the Groups directory title.
+ *
+ * bp-legacy puts the Create a Group button into the page title, to mimic
+ * the behavior of bp-default.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $title Groups directory title.
+ * @return string
+ */
+function bp_legacy_theme_group_create_button( $title ) {
+	return $title . ' ' . bp_get_group_create_button();
+}
+
+/**
+ * Add the Create a Site button to the Sites directory title.
+ *
+ * bp-legacy puts the Create a Site button into the page title, to mimic
+ * the behavior of bp-default.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $title Sites directory title.
+ * @return string
+ */
+function bp_legacy_theme_blog_create_button( $title ) {
+	return $title . ' ' . bp_get_blog_create_button();
+}
 /**
  * This function looks scarier than it actually is. :)
  * Each object loop (activity/members/groups/blogs/forums) contains default
@@ -476,6 +513,11 @@ function bp_legacy_theme_ajax_querystring( $query_string, $object ) {
 		$qs[] = 'exclude=' . implode( ',', $just_posted );
 	}
 
+	// to get newest activities
+	if ( ! empty( $_POST['offset'] ) ) {
+		$qs[] = 'offset=' . intval( $_POST['offset'] );
+	}
+
 	$object_search_text = bp_get_search_default_text( $object );
  	if ( ! empty( $_POST['search_terms'] ) && $object_search_text != $_POST['search_terms'] && 'false' != $_POST['search_terms'] && 'undefined' != $_POST['search_terms'] )
 		$qs[] = 'search_terms=' . $_POST['search_terms'];
@@ -537,8 +579,15 @@ function bp_legacy_theme_object_template_loader() {
 	if ( ! bp_current_action() )
 		bp_update_is_directory( true, bp_current_component() );
 
+	$template_part = $object . '/' . $object . '-loop';
+
+	// The template part can be overridden by the calling JS function
+	if ( ! empty( $_POST['template'] ) ) {
+		$template_part = sanitize_option( 'upload_path', $_POST['template'] );
+	}
+
 	// Locate the object template
-	bp_get_template_part( "$object/$object-loop" );
+	bp_get_template_part( $template_part );
 	exit();
 }
 
@@ -553,6 +602,26 @@ function bp_legacy_theme_messages_template_loader() {
 	exit();
 }
 
+/**
+ * Load group invitations loop to handle pagination requests sent via AJAX.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_legacy_theme_invite_template_loader() {
+	bp_get_template_part( 'groups/single/invites-loop' );
+	exit();
+}
+
+/**
+ * Load group membership requests loop to handle pagination requests sent via AJAX.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_legacy_theme_requests_template_loader() {
+	bp_get_template_part( 'groups/single/requests-loop' );
+	exit();
+}
+
 /**
  * Load the activity loop template when activity is requested via AJAX,
  *
@@ -607,6 +676,8 @@ function bp_legacy_theme_activity_template_loader() {
  * @since BuddyPress (1.2)
  */
 function bp_legacy_theme_post_update() {
+	$bp = buddypress();
+
 	// Bail if not a POST action
 	if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
 		return;
@@ -635,13 +706,26 @@ function bp_legacy_theme_post_update() {
 	if ( empty( $activity_id ) )
 		exit( '-1<div id="message" class="error"><p>' . __( 'There was a problem posting your update, please try again.', 'buddypress' ) . '</p></div>' );
 
-	if ( bp_has_activities ( 'include=' . $activity_id ) ) {
+	$last_recorded = isset( $_POST['since'] ) ? date( 'Y-m-d H:i:s', intval( $_POST['since'] ) ) : 0;
+	if ( $last_recorded ) {
+		$activity_args = array( 'since' => $last_recorded );
+		$bp->activity->last_recorded = $last_recorded;
+		add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
+	} else {
+		$activity_args = array( 'include' => $activity_id );
+	}
+
+	if ( bp_has_activities ( $activity_args ) ) {
 		while ( bp_activities() ) {
 			bp_the_activity();
 			bp_get_template_part( 'activity/entry' );
 		}
 	}
 
+	if ( ! empty( $last_recorded ) ) {
+		remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
+	}
+
 	exit;
 }
 
@@ -688,6 +772,17 @@ function bp_legacy_theme_new_activity_comment() {
 		$activities_template->activity = new stdClass();
 		$activities_template->activity->id              = $activities_template->activities[0]->item_id;
 		$activities_template->activity->current_comment = $activities_template->activities[0];
+
+		// Because the whole tree has not been loaded, we manually
+		// determine depth
+		$depth = 1;
+		$parent_id = $activities_template->activities[0]->secondary_item_id;
+		while ( $parent_id !== $activities_template->activities[0]->item_id ) {
+			$depth++;
+			$p_obj = new BP_Activity_Activity( $parent_id );
+			$parent_id = $p_obj->secondary_item_id;
+		}
+		$activities_template->activity->current_comment->depth = $depth;
 	}
 
 	// get activity comment template part
@@ -772,12 +867,11 @@ function bp_legacy_theme_delete_activity_comment() {
 /**
  * AJAX spam an activity item or comment
  *
- * @global BuddyPress $bp The one true BuddyPress instance
  * @return mixed String on error, void on success
  * @since BuddyPress (1.6)
  */
 function bp_legacy_theme_spam_activity() {
-	global $bp;
+	$bp = buddypress();
 
 	// Bail if not a POST action
 	if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
@@ -905,25 +999,56 @@ function bp_legacy_theme_ajax_invite_user() {
 	if ( ! friends_check_friendship( bp_loggedin_user_id(), $_POST['friend_id'] ) )
 		return;
 
+	$group_id = (int) $_POST['group_id'];
+	$friend_id = (int) $_POST['friend_id'];
+
 	if ( 'invite' == $_POST['friend_action'] ) {
-		if ( ! groups_invite_user( array( 'user_id' => $_POST['friend_id'], 'group_id' => $_POST['group_id'] ) ) )
+		$group = groups_get_group( $group_id );
+
+		// Users who have previously requested membership do not need
+		// another invitation created for them
+		if ( BP_Groups_Member::check_for_membership_request( $friend_id, $group_id ) ) {
+			$user_status = 'is_pending';
+
+		// Create the user invitation
+		} else if ( groups_invite_user( array( 'user_id' => $friend_id, 'group_id' => $group_id ) ) ) {
+			$user_status = 'is_invited';
+
+		// Miscellaneous failure
+		} else {
 			return;
+		}
+
+		$user = new BP_Core_User( $friend_id );
 
-		$user = new BP_Core_User( $_POST['friend_id'] );
+		$uninvite_url = bp_is_current_action( 'create' ) ? bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create/step/group-invites/?user_id=' . $friend_id : bp_get_group_permalink( $group ) . 'send-invites/remove/' . $friend_id;
 
 		echo '<li id="uid-' . $user->id . '">';
 		echo $user->avatar_thumb;
 		echo '<h4>' . $user->user_link . '</h4>';
 		echo '<span class="activity">' . esc_attr( $user->last_active ) . '</span>';
 		echo '<div class="action">
-				<a class="button remove" href="' . wp_nonce_url( bp_loggedin_user_domain() . bp_get_groups_slug() . '/' . $_POST['group_id'] . '/invites/remove/' . $user->id, 'groups_invite_uninvite_user' ) . '" id="uid-' . esc_attr( $user->id ) . '">' . __( 'Remove Invite', 'buddypress' ) . '</a>
+				<a class="button remove" href="' . wp_nonce_url( $uninvite_url, 'groups_invite_uninvite_user' ) . '" id="uid-' . esc_attr( $user->id ) . '">' . __( 'Remove Invite', 'buddypress' ) . '</a>
 			  </div>';
+
+		if ( 'is_pending' == $user_status ) {
+			echo '<p class="description">' . sprintf( __( '%s has previously requested to join this group. Sending an invitation will automatically add the member to the group.', 'buddypress' ), $user->user_link ) . '</p>';
+		}
+
 		echo '</li>';
 		exit;
 
 	} elseif ( 'uninvite' == $_POST['friend_action'] ) {
-		if ( ! groups_uninvite_user( $_POST['friend_id'], $_POST['group_id'] ) )
+		// Users who have previously requested membership should not
+		// have their requests deleted on the "uninvite" action
+		if ( BP_Groups_Member::check_for_membership_request( $friend_id, $group_id ) ) {
 			return;
+		}
+
+		// Remove the unsent invitation
+		if ( ! groups_uninvite_user( $friend_id, $group_id ) ) {
+			return;
+		}
 
 		exit;
 
@@ -1054,12 +1179,27 @@ function bp_legacy_theme_ajax_joinleave_group() {
 			}
 
 		} elseif ( 'private' == $group->status ) {
-			check_ajax_referer( 'groups_request_membership' );
 
-			if ( ! groups_send_membership_request( bp_loggedin_user_id(), $group->id ) ) {
-				_e( 'Error requesting membership', 'buddypress' );
+			// If the user has already been invited, then this is
+			// an Accept Invitation button
+			if ( groups_check_user_has_invite( bp_loggedin_user_id(), $group->id ) ) {
+				check_ajax_referer( 'groups_accept_invite' );
+
+				if ( ! groups_accept_invite( bp_loggedin_user_id(), $group->id ) ) {
+					_e( 'Error requesting membership', 'buddypress' );
+				} else {
+					echo '<a id="group-' . esc_attr( $group->id ) . '" class="leave-group" rel="leave" title="' . __( 'Leave Group', 'buddypress' ) . '" href="' . wp_nonce_url( bp_get_group_permalink( $group ) . 'leave-group', 'groups_leave_group' ) . '">' . __( 'Leave Group', 'buddypress' ) . '</a>';
+				}
+
+			// Otherwise, it's a Request Membership button
 			} else {
-				echo '<a id="group-' . esc_attr( $group->id ) . '" class="membership-requested" rel="membership-requested" title="' . __( 'Membership Requested', 'buddypress' ) . '" href="' . bp_get_group_permalink( $group ) . '">' . __( 'Membership Requested', 'buddypress' ) . '</a>';
+				check_ajax_referer( 'groups_request_membership' );
+
+				if ( ! groups_send_membership_request( bp_loggedin_user_id(), $group->id ) ) {
+					_e( 'Error requesting membership', 'buddypress' );
+				} else {
+					echo '<a id="group-' . esc_attr( $group->id ) . '" class="membership-requested" rel="membership-requested" title="' . __( 'Membership Requested', 'buddypress' ) . '" href="' . bp_get_group_permalink( $group ) . '">' . __( 'Membership Requested', 'buddypress' ) . '</a>';
+				}
 			}
 		}
 
@@ -1224,11 +1364,8 @@ function bp_legacy_theme_ajax_messages_delete() {
 		echo "-1<div id='message' class='error'><p>" . __( 'There was a problem deleting messages.', 'buddypress' ) . '</p></div>';
 
 	} else {
-		$thread_ids = explode( ',', $_POST['thread_ids'] );
-
-		for ( $i = 0, $count = count( $thread_ids ); $i < $count; ++$i ) {
-			BP_Messages_Thread::delete( (int) $thread_ids[$i] );
-		}
+		$thread_ids = wp_parse_id_list( $_POST['thread_ids'] );
+		messages_delete_thread( $thread_ids );
 
 		_e( 'Messages deleted.', 'buddypress' );
 	}
@@ -1237,11 +1374,13 @@ function bp_legacy_theme_ajax_messages_delete() {
 }
 
 /**
- * AJAX handler for autocomplete. Displays friends only, unless BP_MESSAGES_AUTOCOMPLETE_ALL is defined.
+ * AJAX handler for autocomplete.
  *
- * @global BuddyPress $bp The one true BuddyPress instance
- * @return string HTML
- * @since BuddyPress (1.2)
+ * Displays friends only, unless BP_MESSAGES_AUTOCOMPLETE_ALL is defined.
+ *
+ * @since BuddyPress (1.2.0)
+ *
+ * @return string HTML.
  */
 function bp_legacy_theme_ajax_messages_autocomplete_results() {
 
@@ -1249,54 +1388,65 @@ function bp_legacy_theme_ajax_messages_autocomplete_results() {
 	if ( bp_is_current_component( bp_get_messages_slug() ) )
 		$autocomplete_all = buddypress()->messages->autocomplete_all;
 
-	$pag_page = 1;
-	$limit    = (int) $_GET['limit'] ? $_GET['limit'] : apply_filters( 'bp_autocomplete_max_results', 10 );
+	$pag_page     = 1;
+	$limit        = (int) $_GET['limit'] ? $_GET['limit'] : apply_filters( 'bp_autocomplete_max_results', 10 );
+	$search_terms = isset( $_GET['q'] ) ? $_GET['q'] : '';
 
-	// Get the user ids based on the search terms
-	if ( ! empty( $autocomplete_all ) ) {
-		$users = BP_Core_User::search_users( $_GET['q'], $limit, $pag_page );
+	$user_query_args = array(
+		'search_terms' => $search_terms,
+		'page'         => intval( $pag_page ),
+		'per_page'     => intval( $limit ),
+	);
 
-		if ( ! empty( $users['users'] ) ) {
-			// Build an array with the correct format
-			$user_ids = array();
-			foreach( $users['users'] as $user ) {
-				if ( $user->id != bp_loggedin_user_id() ) {
-					$user_ids[] = $user->id;
-				}
-			}
+	// If only matching against friends, get an $include param for
+	// BP_User_Query
+	if ( ! $autocomplete_all && bp_is_active( 'friends' ) ) {
+		$include = BP_Friends_Friendship::get_friend_user_ids( bp_loggedin_user_id() );
 
-			$user_ids = apply_filters( 'bp_core_autocomplete_ids', $user_ids, $_GET['q'], $limit );
+		// Ensure zero matches if no friends are found
+		if ( empty( $include ) ) {
+			$include = array( 0 );
 		}
 
-	} else {
-		if ( bp_is_active( 'friends' ) ) {
-			$users = friends_search_friends( $_GET['q'], bp_loggedin_user_id(), $limit, 1 );
+		$user_query_args['include'] = $include;
+	}
 
-			// Keeping the bp_friends_autocomplete_list filter for backward compatibility
-			$users = apply_filters( 'bp_friends_autocomplete_list', $users, $_GET['q'], $limit );
+	$user_query = new BP_User_Query( $user_query_args );
 
-			if ( ! empty( $users['friends'] ) ) {
-				$user_ids = apply_filters( 'bp_friends_autocomplete_ids', $users['friends'], $_GET['q'], $limit );
-			}
+	// Backward compatibility - if a plugin is expecting a legacy
+	// filter, pass the IDs through the filter and requery (groan)
+	if ( has_filter( 'bp_core_autocomplete_ids' ) || has_filter( 'bp_friends_autocomplete_ids' ) ) {
+		$found_user_ids = wp_list_pluck( $user_query->results, 'ID' );
+
+		if ( $autocomplete_all ) {
+			$found_user_ids = apply_filters( 'bp_core_autocomplete_ids', $found_user_ids );
+		} else {
+			$found_user_ids = apply_filters( 'bp_friends_autocomplete_ids', $found_user_ids );
 		}
-	}
 
-	if ( ! empty( $user_ids ) ) {
-		foreach ( $user_ids as $user_id ) {
-			$ud = get_userdata( $user_id );
-			if ( ! $ud ) {
-				continue;
-			}
+		if ( empty( $found_user_ids ) ) {
+			$found_user_ids = array( 0 );
+		}
+
+		// Repopulate the $user_query variable
+		$user_query = new BP_User_Query( array(
+			'include' => $found_user_ids,
+		) );
+	}
 
+	if ( ! empty( $user_query->results ) ) {
+		foreach ( $user_query->results as $user ) {
 			if ( bp_is_username_compatibility_mode() ) {
-				$username = $ud->user_login;
+				// Sanitize for spaces. Use urlencode() rather
+				// than rawurlencode() because %20 breaks JS
+				$username = urlencode( $user->user_login );
 			} else {
-				$username = $ud->user_nicename;
+				$username = $user->user_nicename;
 			}
 
 			// Note that the final line break acts as a delimiter for the
 			// autocomplete javascript and thus should not be removed
-			echo '<span id="link-' . esc_attr( $username ) . '" href="' . bp_core_get_user_domain( $user_id ) . '"></span>' . bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'thumb', 'width' => 15, 'height' => 15, 'alt' => $ud->display_name ) ) . ' &nbsp;' . bp_core_get_user_displayname( $user_id ) . ' (' . esc_html( $username ) . ')' . "\n";
+			echo '<span id="link-' . esc_attr( $username ) . '" href="' . bp_core_get_user_domain( $user->ID ) . '"></span>' . bp_core_fetch_avatar( array( 'item_id' => $user->ID, 'type' => 'thumb', 'width' => 15, 'height' => 15, 'alt' => $user->display_name ) ) . ' &nbsp;' . bp_core_get_user_displayname( $user->ID ) . ' (' . esc_html( $username ) . ')' . "\n";
 		}
 	}
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/activity-loop.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/activity-loop.php
index 8680b86fe327d4b5909978833eda2467d69db41f..6134ff6bdae96629ede89bfda4acc02b93bb7c67 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/activity-loop.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/activity-loop.php
@@ -46,8 +46,12 @@
 
 <?php do_action( 'bp_after_activity_loop' ); ?>
 
-<form action="" name="activity-loop-form" id="activity-loop-form" method="post">
+<?php if ( empty( $_POST['page'] ) ) : ?>
 
-	<?php wp_nonce_field( 'activity_filter', '_wpnonce_activity_filter' ); ?>
+	<form action="" name="activity-loop-form" id="activity-loop-form" method="post">
 
-</form>
\ No newline at end of file
+		<?php wp_nonce_field( 'activity_filter', '_wpnonce_activity_filter' ); ?>
+
+	</form>
+
+<?php endif; ?>
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/entry.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/entry.php
index b197fbd39e9ad5ddd10f903e0945d90de8630441..24e296b73f606d5ec9219e000236b5e20c78d15a 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/entry.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/entry.php
@@ -47,7 +47,7 @@
 
 			<?php if ( bp_get_activity_type() == 'activity_comment' ) : ?>
 
-				<a href="<?php bp_activity_thread_permalink(); ?>" class="button view bp-secondary-action" title="<?php _e( 'View Conversation', 'buddypress' ); ?>"><?php _e( 'View Conversation', 'buddypress' ); ?></a>
+				<a href="<?php bp_activity_thread_permalink(); ?>" class="button view bp-secondary-action" title="<?php esc_attr_e( 'View Conversation', 'buddypress' ); ?>"><?php _e( 'View Conversation', 'buddypress' ); ?></a>
 
 			<?php endif; ?>
 
@@ -85,7 +85,7 @@
 
 	<?php do_action( 'bp_before_activity_entry_comments' ); ?>
 
-	<?php if ( ( is_user_logged_in() && bp_activity_can_comment() ) || bp_activity_get_comment_count() ) : ?>
+	<?php if ( ( is_user_logged_in() && bp_activity_can_comment() ) || bp_is_single_activity() ) : ?>
 
 		<div class="activity-comments">
 
@@ -99,7 +99,7 @@
 						<div class="ac-textarea">
 							<textarea id="ac-input-<?php bp_activity_id(); ?>" class="ac-input" name="ac_input_<?php bp_activity_id(); ?>"></textarea>
 						</div>
-						<input type="submit" name="ac_form_submit" value="<?php _e( 'Post', 'buddypress' ); ?>" /> &nbsp; <a href="#" class="ac-reply-cancel"><?php _e( 'Cancel', 'buddypress' ); ?></a>
+						<input type="submit" name="ac_form_submit" value="<?php esc_attr_e( 'Post', 'buddypress' ); ?>" /> &nbsp; <a href="#" class="ac-reply-cancel"><?php _e( 'Cancel', 'buddypress' ); ?></a>
 						<input type="hidden" name="comment_form_id" value="<?php bp_activity_id(); ?>" />
 					</div>
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/index.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/index.php
index ce0423e754d38e3e313a44d93643559cb77a431e..de21b6373fb64ed77b94d53a12760741b5c3a86f 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/index.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/index.php
@@ -16,7 +16,7 @@
 		<ul>
 			<?php do_action( 'bp_before_activity_type_tab_all' ); ?>
 
-			<li class="selected" id="activity-all"><a href="<?php bp_activity_directory_permalink(); ?>" title="<?php _e( 'The public activity for everyone on this site.', 'buddypress' ); ?>"><?php printf( __( 'All Members <span>%s</span>', 'buddypress' ), number_format_i18n( bp_get_total_member_count() ) ); ?></a></li>
+			<li class="selected" id="activity-all"><a href="<?php bp_activity_directory_permalink(); ?>" title="<?php esc_attr_e( 'The public activity for everyone on this site.', 'buddypress' ); ?>"><?php printf( __( 'All Members <span>%s</span>', 'buddypress' ), bp_get_total_member_count() ); ?></a></li>
 
 			<?php if ( is_user_logged_in() ) : ?>
 
@@ -26,7 +26,7 @@
 
 					<?php if ( bp_get_total_friend_count( bp_loggedin_user_id() ) ) : ?>
 
-						<li id="activity-friends"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() . '/'; ?>" title="<?php _e( 'The activity of my friends only.', 'buddypress' ); ?>"><?php printf( __( 'My Friends <span>%s</span>', 'buddypress' ), number_format_i18n( bp_get_total_friend_count( bp_loggedin_user_id() ) ) ); ?></a></li>
+						<li id="activity-friends"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() . '/'; ?>" title="<?php esc_attr_e( 'The activity of my friends only.', 'buddypress' ); ?>"><?php printf( __( 'My Friends <span>%s</span>', 'buddypress' ), bp_get_total_friend_count( bp_loggedin_user_id() ) ); ?></a></li>
 
 					<?php endif; ?>
 
@@ -38,7 +38,7 @@
 
 					<?php if ( bp_get_total_group_count_for_user( bp_loggedin_user_id() ) ) : ?>
 
-						<li id="activity-groups"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() . '/'; ?>" title="<?php _e( 'The activity of groups I am a member of.', 'buddypress' ); ?>"><?php printf( __( 'My Groups <span>%s</span>', 'buddypress' ), number_format_i18n( bp_get_total_group_count_for_user( bp_loggedin_user_id() ) ) ); ?></a></li>
+						<li id="activity-groups"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() . '/'; ?>" title="<?php esc_attr_e( 'The activity of groups I am a member of.', 'buddypress' ); ?>"><?php printf( __( 'My Groups <span>%s</span>', 'buddypress' ), bp_get_total_group_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
 
 					<?php endif; ?>
 
@@ -48,7 +48,7 @@
 
 				<?php if ( bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ) : ?>
 
-					<li id="activity-favorites"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/'; ?>" title="<?php _e( "The activity I've marked as a favorite.", 'buddypress' ); ?>"><?php printf( __( 'My Favorites <span>%s</span>', 'buddypress' ), number_format_i18n( bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ) ); ?></a></li>
+					<li id="activity-favorites"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/'; ?>" title="<?php esc_attr_e( "The activity I've marked as a favorite.", 'buddypress' ); ?>"><?php printf( __( 'My Favorites <span>%s</span>', 'buddypress' ), bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
 
 				<?php endif; ?>
 
@@ -56,7 +56,7 @@
 
 					<?php do_action( 'bp_before_activity_type_tab_mentions' ); ?>
 
-					<li id="activity-mentions"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/'; ?>" title="<?php _e( 'Activity that I have been mentioned in.', 'buddypress' ); ?>"><?php _e( 'Mentions', 'buddypress' ); ?><?php if ( bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ) : ?> <strong><span><?php printf( _nx( '%s new', '%s new', bp_get_total_mention_count_for_user( bp_loggedin_user_id() ), 'Number of new activity mentions', 'buddypress' ), number_format_i18n( bp_get_total_mention_count_for_user( bp_loggedin_user_id()  )) ); ?></span></strong><?php endif; ?></a></li>
+					<li id="activity-mentions"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/'; ?>" title="<?php esc_attr_e( 'Activity that I have been mentioned in.', 'buddypress' ); ?>"><?php _e( 'Mentions', 'buddypress' ); ?><?php if ( bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ) : ?> <strong><span><?php printf( _nx( '%s new', '%s new', bp_get_total_mention_count_for_user( bp_loggedin_user_id() ), 'Number of new activity mentions', 'buddypress' ), bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ); ?></span></strong><?php endif; ?></a></li>
 
 				<?php endif; ?>
 
@@ -68,7 +68,7 @@
 
 	<div class="item-list-tabs no-ajax" id="subnav" role="navigation">
 		<ul>
-			<li class="feed"><a href="<?php bp_sitewide_activity_feed_link(); ?>" title="<?php _e( 'RSS Feed', 'buddypress' ); ?>"><?php _e( 'RSS', 'buddypress' ); ?></a></li>
+			<li class="feed"><a href="<?php bp_sitewide_activity_feed_link(); ?>" title="<?php esc_attr_e( 'RSS Feed', 'buddypress' ); ?>"><?php _e( 'RSS', 'buddypress' ); ?></a></li>
 
 			<?php do_action( 'bp_activity_syndication_options' ); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/post-form.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/post-form.php
index c7ada634ecb93b11433a3fa645444a134da1ab97..c8577a246dced7051f7b8ae502542758fa56ad89 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/post-form.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/activity/post-form.php
@@ -27,12 +27,12 @@
 
 	<div id="whats-new-content">
 		<div id="whats-new-textarea">
-			<textarea name="whats-new" id="whats-new" cols="50" rows="10"><?php if ( isset( $_GET['r'] ) ) : ?>@<?php echo esc_attr( $_GET['r'] ); ?> <?php endif; ?></textarea>
+			<textarea name="whats-new" id="whats-new" cols="50" rows="10"><?php if ( isset( $_GET['r'] ) ) : ?>@<?php echo esc_textarea( $_GET['r'] ); ?> <?php endif; ?></textarea>
 		</div>
 
 		<div id="whats-new-options">
 			<div id="whats-new-submit">
-				<input type="submit" name="aw-whats-new-submit" id="aw-whats-new-submit" value="<?php _e( 'Post Update', 'buddypress' ); ?>" />
+				<input type="submit" name="aw-whats-new-submit" id="aw-whats-new-submit" value="<?php esc_attr_e( 'Post Update', 'buddypress' ); ?>" />
 			</div>
 
 			<?php if ( bp_is_active( 'groups' ) && !bp_is_my_profile() && !bp_is_group() ) : ?>
@@ -44,7 +44,7 @@
 					<select id="whats-new-post-in" name="whats-new-post-in">
 						<option selected="selected" value="0"><?php _e( 'My Profile', 'buddypress' ); ?></option>
 
-						<?php if ( bp_has_groups( 'user_id=' . bp_loggedin_user_id() . '&type=alphabetical&max=100&per_page=100&populate_extras=0' ) ) :
+						<?php if ( bp_has_groups( 'user_id=' . bp_loggedin_user_id() . '&type=alphabetical&max=100&per_page=100&populate_extras=0&update_meta_cache=0' ) ) :
 							while ( bp_groups() ) : bp_the_group(); ?>
 
 								<option value="<?php bp_group_id(); ?>"><?php bp_group_name(); ?></option>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/forums/forums-loop.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/forums/forums-loop.php
index 3c4022526ecbfbc249d4f0d89d0ee01e0f571215..9d822667f296461a163b385e69da87de43e92604 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/forums/forums-loop.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/forums/forums-loop.php
@@ -51,7 +51,7 @@
 
 			<tr class="<?php bp_the_topic_css_class(); ?>">
 				<td class="td-title">
-					<a class="topic-title" href="<?php bp_the_topic_permalink(); ?>" title="<?php _e( 'Permanent link to this post', 'buddypress' ); ?>">
+					<a class="topic-title" href="<?php bp_the_topic_permalink(); ?>" title="<?php esc_attr_e( 'Permanent link to this post', 'buddypress' ); ?>">
 
 						<?php bp_the_topic_title(); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/forums/index.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/forums/index.php
index 944f0d1f3feb33fc2504e3fa6af50c2c6d648c9c..0f5544386ee0e039e5aa614b32ac8fa0f5623a34 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/forums/index.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/forums/index.php
@@ -112,8 +112,8 @@
 					<?php do_action( 'groups_forum_new_topic_after' ); ?>
 
 					<div class="submit">
-						<input type="submit" name="submit_topic" id="submit" value="<?php _e( 'Post Topic', 'buddypress' ); ?>" />
-						<input type="button" name="submit_topic_cancel" id="submit_topic_cancel" value="<?php _e( 'Cancel', 'buddypress' ); ?>" />
+						<input type="submit" name="submit_topic" id="submit" value="<?php esc_attr_e( 'Post Topic', 'buddypress' ); ?>" />
+						<input type="button" name="submit_topic_cancel" id="submit_topic_cancel" value="<?php esc_attr_e( 'Cancel', 'buddypress' ); ?>" />
 					</div>
 
 					<?php wp_nonce_field( 'bp_forums_new_topic' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/create.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/create.php
index 35573ba4cfd91b870aeffe909856b93907a0a97a..b90223dde60ba7ba223bff0b1c80bc99a1af7b57 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/create.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/create.php
@@ -143,7 +143,7 @@
 
 						<p>
 							<input type="file" name="file" id="file" />
-							<input type="submit" name="upload" id="upload" value="<?php _e( 'Upload Image', 'buddypress' ); ?>" />
+							<input type="submit" name="upload" id="upload" value="<?php esc_attr_e( 'Upload Image', 'buddypress' ); ?>" />
 							<input type="hidden" name="action" id="action" value="bp_avatar_upload" />
 						</p>
 
@@ -156,13 +156,13 @@
 
 					<h4><?php _e( 'Crop Group Avatar', 'buddypress' ); ?></h4>
 
-					<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php _e( 'Avatar to crop', 'buddypress' ); ?>" />
+					<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php esc_attr_e( 'Avatar to crop', 'buddypress' ); ?>" />
 
 					<div id="avatar-crop-pane">
-						<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php _e( 'Avatar preview', 'buddypress' ); ?>" />
+						<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php esc_attr_e( 'Avatar preview', 'buddypress' ); ?>" />
 					</div>
 
-					<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php _e( 'Crop Image', 'buddypress' ); ?>" />
+					<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php esc_attr_e( 'Crop Image', 'buddypress' ); ?>" />
 
 					<input type="hidden" name="image_src" id="image_src" value="<?php bp_avatar_to_crop_src(); ?>" />
 					<input type="hidden" name="upload" id="upload" />
@@ -258,28 +258,28 @@
 					<?php /* Previous Button */ ?>
 					<?php if ( !bp_is_first_group_creation_step() ) : ?>
 
-						<input type="button" value="<?php _e( 'Back to Previous Step', 'buddypress' ); ?>" id="group-creation-previous" name="previous" onclick="location.href='<?php bp_group_creation_previous_link(); ?>'" />
+						<input type="button" value="<?php esc_attr_e( 'Back to Previous Step', 'buddypress' ); ?>" id="group-creation-previous" name="previous" onclick="location.href='<?php bp_group_creation_previous_link(); ?>'" />
 
 					<?php endif; ?>
 
 					<?php /* Next Button */ ?>
 					<?php if ( !bp_is_last_group_creation_step() && !bp_is_first_group_creation_step() ) : ?>
 
-						<input type="submit" value="<?php _e( 'Next Step', 'buddypress' ); ?>" id="group-creation-next" name="save" />
+						<input type="submit" value="<?php esc_attr_e( 'Next Step', 'buddypress' ); ?>" id="group-creation-next" name="save" />
 
 					<?php endif;?>
 
 					<?php /* Create Button */ ?>
 					<?php if ( bp_is_first_group_creation_step() ) : ?>
 
-						<input type="submit" value="<?php _e( 'Create Group and Continue', 'buddypress' ); ?>" id="group-creation-create" name="save" />
+						<input type="submit" value="<?php esc_attr_e( 'Create Group and Continue', 'buddypress' ); ?>" id="group-creation-create" name="save" />
 
 					<?php endif; ?>
 
 					<?php /* Finish Button */ ?>
 					<?php if ( bp_is_last_group_creation_step() ) : ?>
 
-						<input type="submit" value="<?php _e( 'Finish', 'buddypress' ); ?>" id="group-creation-finish" name="save" />
+						<input type="submit" value="<?php esc_attr_e( 'Finish', 'buddypress' ); ?>" id="group-creation-finish" name="save" />
 
 					<?php endif; ?>
 				</div>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/groups-loop.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/groups-loop.php
index 6ba22233aaf5e68f0ceb1232b1395a42cf94ef2b..9302d1348dcfe0a248ede7c83e6c9ff1b4335c4d 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/groups-loop.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/groups-loop.php
@@ -37,7 +37,7 @@
 
 	<?php while ( bp_groups() ) : bp_the_group(); ?>
 
-		<li>
+		<li <?php bp_group_class(); ?>>
 			<div class="item-avatar">
 				<a href="<?php bp_group_permalink(); ?>"><?php bp_group_avatar( 'type=thumb&width=50&height=50' ); ?></a>
 			</div>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/activity.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/activity.php
index 79b18d04a8c093b80d8cabb182806bc5ceba60ad..ff2c6d90943426aba2ae16dfa17be6246af9c25c 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/activity.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/activity.php
@@ -1,6 +1,6 @@
 <div class="item-list-tabs no-ajax" id="subnav" role="navigation">
 	<ul>
-		<li class="feed"><a href="<?php bp_group_activity_feed_link(); ?>" title="<?php _e( 'RSS Feed', 'buddypress' ); ?>"><?php _e( 'RSS', 'buddypress' ); ?></a></li>
+		<li class="feed"><a href="<?php bp_group_activity_feed_link(); ?>" title="<?php esc_attr_e( 'RSS Feed', 'buddypress' ); ?>"><?php _e( 'RSS', 'buddypress' ); ?></a></li>
 
 		<?php do_action( 'bp_group_activity_syndication_options' ); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/admin.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/admin.php
index 449a7bfa5170e9ec1c66067717343541bde3a764..90dfb3b1e74be0d334c44c0f9ccf3ececcf0418e 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/admin.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/admin.php
@@ -29,7 +29,7 @@
 
 	<?php do_action( 'bp_after_group_details_admin' ); ?>
 
-	<p><input type="submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" id="save" name="save" /></p>
+	<p><input type="submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="save" name="save" /></p>
 	<?php wp_nonce_field( 'groups_edit_group_details' ); ?>
 
 <?php endif; ?>
@@ -114,7 +114,7 @@
 
 	<?php do_action( 'bp_after_group_settings_admin' ); ?>
 
-	<p><input type="submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" id="save" name="save" /></p>
+	<p><input type="submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="save" name="save" /></p>
 	<?php wp_nonce_field( 'groups_edit_group_settings' ); ?>
 
 <?php endif; ?>
@@ -128,7 +128,7 @@
 
 			<p>
 				<input type="file" name="file" id="file" />
-				<input type="submit" name="upload" id="upload" value="<?php _e( 'Upload Image', 'buddypress' ); ?>" />
+				<input type="submit" name="upload" id="upload" value="<?php esc_attr_e( 'Upload Image', 'buddypress' ); ?>" />
 				<input type="hidden" name="action" id="action" value="bp_avatar_upload" />
 			</p>
 
@@ -148,13 +148,13 @@
 
 		<h4><?php _e( 'Crop Avatar', 'buddypress' ); ?></h4>
 
-		<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php _e( 'Avatar to crop', 'buddypress' ); ?>" />
+		<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php esc_attr_e( 'Avatar to crop', 'buddypress' ); ?>" />
 
 		<div id="avatar-crop-pane">
-			<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php _e( 'Avatar preview', 'buddypress' ); ?>" />
+			<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php esc_attr_e( 'Avatar preview', 'buddypress' ); ?>" />
 		</div>
 
-		<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php _e( 'Crop Image', 'buddypress' ); ?>" />
+		<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php esc_attr_e( 'Crop Image', 'buddypress' ); ?>" />
 
 		<input type="hidden" name="image_src" id="image_src" value="<?php bp_avatar_to_crop_src(); ?>" />
 		<input type="hidden" id="x" name="x" />
@@ -213,7 +213,7 @@
 						<h5>
 							<a href="<?php bp_member_permalink(); ?>"> <?php bp_member_name(); ?></a>
 							<span class="small">
-								<a href="<?php bp_group_member_promote_admin_link( array( 'user_id' => bp_get_member_user_id() ) ); ?>" class="button confirm mod-promote-to-admin" title="<?php _e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_promote_admin_link( array( 'user_id' => bp_get_member_user_id() ) ); ?>" class="button confirm mod-promote-to-admin" title="<?php esc_attr_e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
 								<a class="button confirm mod-demote-to-member" href="<?php bp_group_member_demote_link( bp_get_member_user_id() ); ?>"><?php _e( 'Demote to Member', 'buddypress' ); ?></a>
 							</span>
 						</h5>
@@ -263,17 +263,17 @@
 
 							<?php if ( bp_get_group_member_is_banned() ) : ?>
 
-								<a href="<?php bp_group_member_unban_link(); ?>" class="button confirm member-unban" title="<?php _e( 'Unban this member', 'buddypress' ); ?>"><?php _e( 'Remove Ban', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_unban_link(); ?>" class="button confirm member-unban" title="<?php esc_attr_e( 'Unban this member', 'buddypress' ); ?>"><?php _e( 'Remove Ban', 'buddypress' ); ?></a>
 
 							<?php else : ?>
 
-								<a href="<?php bp_group_member_ban_link(); ?>" class="button confirm member-ban" title="<?php _e( 'Kick and ban this member', 'buddypress' ); ?>"><?php _e( 'Kick &amp; Ban', 'buddypress' ); ?></a>
-								<a href="<?php bp_group_member_promote_mod_link(); ?>" class="button confirm member-promote-to-mod" title="<?php _e( 'Promote to Mod', 'buddypress' ); ?>"><?php _e( 'Promote to Mod', 'buddypress' ); ?></a>
-								<a href="<?php bp_group_member_promote_admin_link(); ?>" class="button confirm member-promote-to-admin" title="<?php _e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_ban_link(); ?>" class="button confirm member-ban" title="<?php esc_attr_e( 'Kick and ban this member', 'buddypress' ); ?>"><?php _e( 'Kick &amp; Ban', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_promote_mod_link(); ?>" class="button confirm member-promote-to-mod" title="<?php esc_attr_e( 'Promote to Mod', 'buddypress' ); ?>"><?php _e( 'Promote to Mod', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_promote_admin_link(); ?>" class="button confirm member-promote-to-admin" title="<?php esc_attr_e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
 
 							<?php endif; ?>
 
-								<a href="<?php bp_group_member_remove_link(); ?>" class="button confirm" title="<?php _e( 'Remove this member', 'buddypress' ); ?>"><?php _e( 'Remove from group', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_remove_link(); ?>" class="button confirm" title="<?php esc_attr_e( 'Remove this member', 'buddypress' ); ?>"><?php _e( 'Remove from group', 'buddypress' ); ?></a>
 
 								<?php do_action( 'bp_group_manage_members_admin_item' ); ?>
 
@@ -303,40 +303,12 @@
 
 	<?php do_action( 'bp_before_group_membership_requests_admin' ); ?>
 
-	<?php if ( bp_group_has_membership_requests() ) : ?>
+		<div class="requests">
 
-		<ul id="request-list" class="item-list">
-			<?php while ( bp_group_membership_requests() ) : bp_group_the_membership_request(); ?>
+			<?php bp_get_template_part( 'groups/single/requests-loop' ); ?>
 
-				<li>
-					<?php bp_group_request_user_avatar_thumb(); ?>
-					<h4><?php bp_group_request_user_link(); ?> <span class="comments"><?php bp_group_request_comment(); ?></span></h4>
-					<span class="activity"><?php bp_group_request_time_since_requested(); ?></span>
-
-					<?php do_action( 'bp_group_membership_requests_admin_item' ); ?>
-
-					<div class="action">
-
-						<?php bp_button( array( 'id' => 'group_membership_accept', 'component' => 'groups', 'wrapper_class' => 'accept', 'link_href' => bp_get_group_request_accept_link(), 'link_title' => __( 'Accept', 'buddypress' ), 'link_text' => __( 'Accept', 'buddypress' ) ) ); ?>
-
-						<?php bp_button( array( 'id' => 'group_membership_reject', 'component' => 'groups', 'wrapper_class' => 'reject', 'link_href' => bp_get_group_request_reject_link(), 'link_title' => __( 'Reject', 'buddypress' ), 'link_text' => __( 'Reject', 'buddypress' ) ) ); ?>
-
-						<?php do_action( 'bp_group_membership_requests_admin_item_action' ); ?>
-
-					</div>
-				</li>
-
-			<?php endwhile; ?>
-		</ul>
-
-	<?php else: ?>
-
-		<div id="message" class="info">
-			<p><?php _e( 'There are no pending membership requests.', 'buddypress' ); ?></p>
 		</div>
 
-	<?php endif; ?>
-
 	<?php do_action( 'bp_after_group_membership_requests_admin' ); ?>
 
 <?php endif; ?>
@@ -357,7 +329,7 @@
 	<?php do_action( 'bp_after_group_delete_admin' ); ?>
 
 	<div class="submit">
-		<input type="submit" disabled="disabled" value="<?php _e( 'Delete Group', 'buddypress' ); ?>" id="delete-group-button" name="delete-group-button" />
+		<input type="submit" disabled="disabled" value="<?php esc_attr_e( 'Delete Group', 'buddypress' ); ?>" id="delete-group-button" name="delete-group-button" />
 	</div>
 
 	<?php wp_nonce_field( 'groups_delete_group' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum.php
index 97b670a12d0e30f0a0b4920097b39e36bd29a814..f636732f393edad5f5179885f6c1f8bcbd2c368b 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum.php
@@ -84,7 +84,7 @@ else : ?>
 				<?php do_action( 'bp_after_group_forum_post_new' ); ?>
 
 				<div class="submit">
-					<input type="submit" name="submit_topic" id="submit" value="<?php _e( 'Post Topic', 'buddypress' ); ?>" />
+					<input type="submit" name="submit_topic" id="submit" value="<?php esc_attr_e( 'Post Topic', 'buddypress' ); ?>" />
 				</div>
 
 				<?php wp_nonce_field( 'bp_forums_new_topic' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php
index 0005ff28fabce551d1fc72db9d222dbf24ead6fe..1849a87052dccc89638cb06244ee4ffa24a5ea88 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php
@@ -55,7 +55,7 @@
 
 				<?php do_action( 'bp_group_after_edit_forum_topic' ); ?>
 
-				<p class="submit"><input type="submit" name="save_changes" id="save_changes" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" /></p>
+				<p class="submit"><input type="submit" name="save_changes" id="save_changes" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" /></p>
 
 				<?php wp_nonce_field( 'bp_forums_edit_topic' ); ?>
 
@@ -71,7 +71,7 @@
 
 				<?php do_action( 'bp_group_after_edit_forum_post' ); ?>
 
-				<p class="submit"><input type="submit" name="save_changes" id="save_changes" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" /></p>
+				<p class="submit"><input type="submit" name="save_changes" id="save_changes" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" /></p>
 
 				<?php wp_nonce_field( 'bp_forums_edit_post' ); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum/topic.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum/topic.php
index a13ac07e0626652051245b89329b391d977e165f..50494d575e998c786913c4717858a14947f5db4c 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum/topic.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/forum/topic.php
@@ -92,7 +92,7 @@
 
 						<?php do_action( 'bp_group_forum_post_meta' ); ?>
 
-						<a href="#post-<?php bp_the_topic_post_id(); ?>" title="<?php _e( 'Permanent link to this post', 'buddypress' ); ?>">#</a>
+						<a href="#post-<?php bp_the_topic_post_id(); ?>" title="<?php esc_attr_e( 'Permanent link to this post', 'buddypress' ); ?>">#</a>
 					</div>
 				</li>
 
@@ -141,7 +141,7 @@
 					<textarea name="reply_text" id="reply_text"></textarea>
 
 					<div class="submit">
-						<input type="submit" name="submit_reply" id="submit" value="<?php _e( 'Post Reply', 'buddypress' ); ?>" />
+						<input type="submit" name="submit_reply" id="submit" value="<?php esc_attr_e( 'Post Reply', 'buddypress' ); ?>" />
 					</div>
 
 					<?php do_action( 'groups_forum_new_reply_after' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/home.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/home.php
index 55dd5b000aaffd44106abbeae153ccbbb1a2ae12..11dfb2e5cff293958b02ba0e5e72d026cec4c76d 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/home.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/home.php
@@ -47,7 +47,7 @@
 				elseif ( bp_is_active( 'activity' ) ) : bp_get_template_part( 'groups/single/activity' );
 
 				// Otherwise show members
-				elseif ( bp_is_active( 'members'  ) ) : bp_get_template_part( 'groups/single/members'  );
+				elseif ( bp_is_active( 'members'  ) ) : bp_groups_members_template_part();
 
 				endif;
 				
@@ -61,7 +61,7 @@
 				elseif ( bp_is_group_activity()   ) : bp_get_template_part( 'groups/single/activity'     );
 
 				// Group Members
-				elseif ( bp_is_group_members()    ) : bp_get_template_part( 'groups/single/members'      );
+				elseif ( bp_is_group_members()    ) : bp_groups_members_template_part();
 
 				// Group Invitations
 				elseif ( bp_is_group_invites()    ) : bp_get_template_part( 'groups/single/send-invites' );
@@ -69,6 +69,9 @@
 				// Old group forums
 				elseif ( bp_is_group_forum()      ) : bp_get_template_part( 'groups/single/forum'        );
 
+				// Membership request
+				elseif ( bp_is_group_membership_request() ) : bp_get_template_part( 'groups/single/request-membership' );
+
 				// Anything else (plugins mostly)
 				else                                : bp_get_template_part( 'groups/single/plugins'      );
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/invites-loop.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/invites-loop.php
new file mode 100644
index 0000000000000000000000000000000000000000..ffc11644280d042e4b2cefcca3fcaafeaf8e1151
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/invites-loop.php
@@ -0,0 +1,93 @@
+<div class="left-menu">
+
+	<div id="invite-list">
+
+		<ul>
+			<?php bp_new_group_invite_friend_list(); ?>
+		</ul>
+
+		<?php wp_nonce_field( 'groups_invite_uninvite_user', '_wpnonce_invite_uninvite_user' ); ?>
+
+	</div>
+
+</div><!-- .left-menu -->
+
+<div class="main-column">
+
+	<?php do_action( 'bp_before_group_send_invites_list' ); ?>
+
+	<?php if ( bp_group_has_invites( bp_ajax_querystring( 'invite' ) . '&per_page=10' ) ) : ?>
+
+		<div id="pag-top" class="pagination">
+
+			<div class="pag-count" id="group-invite-count-top">
+
+				<?php bp_group_invite_pagination_count(); ?>
+
+			</div>
+
+			<div class="pagination-links" id="group-invite-pag-top">
+
+				<?php bp_group_invite_pagination_links(); ?>
+
+			</div>
+
+		</div>
+
+		<?php /* The ID 'friend-list' is important for AJAX support. */ ?>
+		<ul id="friend-list" class="item-list">
+
+		<?php while ( bp_group_invites() ) : bp_group_the_invite(); ?>
+
+			<li id="<?php bp_group_invite_item_id(); ?>">
+				<?php bp_group_invite_user_avatar(); ?>
+
+				<h4><?php bp_group_invite_user_link(); ?></h4>
+				<span class="activity"><?php bp_group_invite_user_last_active(); ?></span>
+
+				<?php do_action( 'bp_group_send_invites_item' ); ?>
+
+				<div class="action">
+					<a class="button remove" href="<?php bp_group_invite_user_remove_invite_url(); ?>" id="<?php bp_group_invite_item_id(); ?>"><?php _e( 'Remove Invite', 'buddypress' ); ?></a>
+
+					<?php do_action( 'bp_group_send_invites_item_action' ); ?>
+				</div>
+			</li>
+
+		<?php endwhile; ?>
+
+		</ul><!-- #friend-list -->
+
+		<div id="pag-bottom" class="pagination">
+
+			<div class="pag-count" id="group-invite-count-bottom">
+
+				<?php bp_group_invite_pagination_count(); ?>
+
+			</div>
+
+			<div class="pagination-links" id="group-invite-pag-bottom">
+
+				<?php bp_group_invite_pagination_links(); ?>
+
+			</div>
+
+		</div>
+
+	<?php else : ?>
+		<div id="message" class="info">
+			<p><?php _e( 'Select people to invite from your friends list.', 'buddypress' ); ?></p>
+		</div>
+	<?php endif; ?>
+
+<?php do_action( 'bp_after_group_send_invites_list' ); ?>
+
+</div><!-- .main-column -->
+
+<div class="clear"></div>
+
+<div class="submit">
+	<input type="submit" name="submit" id="submit" value="<?php esc_attr_e( 'Send Invites', 'buddypress' ); ?>" />
+</div>
+
+<?php wp_nonce_field( 'groups_send_invites', '_wpnonce_send_invites' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/members.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/members.php
index fb7b4e2e99f01338455cf2b106dc5d44ba6fbcaa..f1714a5ae24a842fb7c7f6a51743ef8ce907f63e 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/members.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/members.php
@@ -1,16 +1,8 @@
-<?php if ( bp_group_has_members( 'exclude_admins_mods=0' ) ) : ?>
+<?php if ( bp_group_has_members( bp_ajax_querystring( 'group_members' ) ) ) : ?>
 
 	<?php do_action( 'bp_before_group_members_content' ); ?>
 
-	<div class="item-list-tabs" id="subnav" role="navigation">
-		<ul>
-
-			<?php do_action( 'bp_members_directory_member_sub_types' ); ?>
-
-		</ul>
-	</div>
-
-	<div id="pag-top" class="pagination no-ajax">
+	<div id="pag-top" class="pagination">
 
 		<div class="pag-count" id="member-count-top">
 
@@ -63,7 +55,7 @@
 
 	<?php do_action( 'bp_after_group_members_list' ); ?>
 
-	<div id="pag-bottom" class="pagination no-ajax">
+	<div id="pag-bottom" class="pagination">
 
 		<div class="pag-count" id="member-count-bottom">
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/plugins.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/plugins.php
index c8e2f47d54a578068635e7fbc493f33bd2bb607a..c9d34f83d8be3aeeaecaf2fe6b8c59b56d1b58df 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/plugins.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/plugins.php
@@ -1,13 +1,5 @@
 <?php do_action( 'bp_before_group_plugin_template' ); ?>
 
-<div id="item-body">
-
-	<?php do_action( 'bp_before_group_body' ); ?>
-
-	<?php do_action( 'bp_template_content' ); ?>
-
-	<?php do_action( 'bp_after_group_body' ); ?>
-
-</div><!-- #item-body -->
+<?php do_action( 'bp_template_content' ); ?>
 
 <?php do_action( 'bp_after_group_plugin_template' );
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/request-membership.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/request-membership.php
index fd9635810c583d776639c17742286532626f71c3..6af798b21100510beced0a56e2b0da9f31b54b78 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/request-membership.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/request-membership.php
@@ -9,7 +9,7 @@
 
 		<?php do_action( 'bp_group_request_membership_content' ); ?>
 
-		<p><input type="submit" name="group-request-send" id="group-request-send" value="<?php _e( 'Send Request', 'buddypress' ); ?>" />
+		<p><input type="submit" name="group-request-send" id="group-request-send" value="<?php esc_attr_e( 'Send Request', 'buddypress' ); ?>" />
 
 		<?php wp_nonce_field( 'groups_request_membership' ); ?>
 	</form><!-- #request-membership-form -->
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/requests-loop.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/requests-loop.php
new file mode 100644
index 0000000000000000000000000000000000000000..0148cbb27104be7919f16ff17b100bb353bb36ac
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/requests-loop.php
@@ -0,0 +1,65 @@
+<?php if ( bp_group_has_membership_requests( bp_ajax_querystring( 'membership_requests' ) ) ) : ?>
+
+	<div id="pag-top" class="pagination">
+
+		<div class="pag-count" id="group-mem-requests-count-top">
+
+			<?php bp_group_requests_pagination_count(); ?>
+
+		</div>
+
+		<div class="pagination-links" id="group-mem-requests-pag-top">
+
+			<?php bp_group_requests_pagination_links(); ?>
+
+		</div>
+
+	</div>
+
+	<ul id="request-list" class="item-list">
+		<?php while ( bp_group_membership_requests() ) : bp_group_the_membership_request(); ?>
+
+			<li>
+				<?php bp_group_request_user_avatar_thumb(); ?>
+				<h4><?php bp_group_request_user_link(); ?> <span class="comments"><?php bp_group_request_comment(); ?></span></h4>
+				<span class="activity"><?php bp_group_request_time_since_requested(); ?></span>
+
+				<?php do_action( 'bp_group_membership_requests_admin_item' ); ?>
+
+				<div class="action">
+
+					<?php bp_button( array( 'id' => 'group_membership_accept', 'component' => 'groups', 'wrapper_class' => 'accept', 'link_href' => bp_get_group_request_accept_link(), 'link_title' => __( 'Accept', 'buddypress' ), 'link_text' => __( 'Accept', 'buddypress' ) ) ); ?>
+
+					<?php bp_button( array( 'id' => 'group_membership_reject', 'component' => 'groups', 'wrapper_class' => 'reject', 'link_href' => bp_get_group_request_reject_link(), 'link_title' => __( 'Reject', 'buddypress' ), 'link_text' => __( 'Reject', 'buddypress' ) ) ); ?>
+
+					<?php do_action( 'bp_group_membership_requests_admin_item_action' ); ?>
+
+				</div>
+			</li>
+
+		<?php endwhile; ?>
+	</ul>
+
+	<div id="pag-bottom" class="pagination">
+
+		<div class="pag-count" id="group-mem-requests-count-bottom">
+
+			<?php bp_group_requests_pagination_count(); ?>
+
+		</div>
+
+		<div class="pagination-links" id="group-mem-requests-pag-bottom">
+
+			<?php bp_group_requests_pagination_links(); ?>
+
+		</div>
+
+	</div>
+
+	<?php else: ?>
+
+		<div id="message" class="info">
+			<p><?php _e( 'There are no pending membership requests.', 'buddypress' ); ?></p>
+		</div>
+
+	<?php endif; ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/send-invites.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/send-invites.php
index 4d30849b78348ef77bd28307d47287477b4806aa..6f3d9ef60899bb13ad24e1b149ffab0db72a3213 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/send-invites.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/groups/single/send-invites.php
@@ -2,77 +2,20 @@
 
 <?php if ( bp_get_total_friend_count( bp_loggedin_user_id() ) ) : ?>
 
+	<?php /* 'send-invite-form' is important for AJAX support */ ?>
 	<form action="<?php bp_group_send_invite_form_action(); ?>" method="post" id="send-invite-form" class="standard-form" role="main">
 
-		<div class="left-menu">
+		<div class="invite">
 
-			<div id="invite-list">
-				<ul>
-					<?php bp_new_group_invite_friend_list(); ?>
-				</ul>
+			<?php bp_get_template_part( 'groups/single/invites-loop' ); ?>
 
-				<?php wp_nonce_field( 'groups_invite_uninvite_user', '_wpnonce_invite_uninvite_user' ); ?>
-			</div>
-
-		</div><!-- .left-menu -->
-
-		<div class="main-column">
-
-			<div id="message" class="info">
-				<p><?php _e('Select people to invite from your friends list.', 'buddypress' ); ?></p>
-			</div>
-
-			<?php do_action( 'bp_before_group_send_invites_list' ); ?>
-
-			<?php /* The ID 'friend-list' is important for AJAX support. */ ?>
-			<ul id="friend-list" class="item-list">
-			<?php if ( bp_group_has_invites() ) : ?>
-
-				<?php while ( bp_group_invites() ) : bp_group_the_invite(); ?>
-
-					<li id="<?php bp_group_invite_item_id(); ?>">
-						<?php bp_group_invite_user_avatar(); ?>
-
-						<h4><?php bp_group_invite_user_link(); ?></h4>
-						<span class="activity"><?php bp_group_invite_user_last_active(); ?></span>
-
-						<?php do_action( 'bp_group_send_invites_item' ); ?>
-
-						<div class="action">
-							<a class="button remove" href="<?php bp_group_invite_user_remove_invite_url(); ?>" id="<?php bp_group_invite_item_id(); ?>"><?php _e( 'Remove Invite', 'buddypress' ); ?></a>
-
-							<?php do_action( 'bp_group_send_invites_item_action' ); ?>
-						</div>
-					</li>
-
-				<?php endwhile; ?>
-
-			<?php endif; ?>
-			</ul><!-- #friend-list -->
-
-			<?php do_action( 'bp_after_group_send_invites_list' ); ?>
-
-		</div><!-- .main-column -->
-
-		<div class="clear"></div>
-
-		<div class="submit">
-			<input type="submit" name="submit" id="submit" value="<?php _e( 'Send Invites', 'buddypress' ); ?>" />
 		</div>
 
-		<?php wp_nonce_field( 'groups_send_invites', '_wpnonce_send_invites' ); ?>
-
 		<?php /* This is important, don't forget it */ ?>
 		<input type="hidden" name="group_id" id="group_id" value="<?php bp_group_id(); ?>" />
 
 	</form><!-- #send-invite-form -->
 
-<?php else : ?>
-
-	<div id="message" class="info" role="main">
-		<p><?php _e( 'Once you have built up friend connections you will be able to invite others to your group.', 'buddypress' ); ?></p>
-	</div>
-
 <?php endif; ?>
 
 <?php do_action( 'bp_after_group_send_invites_content' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/activate.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/activate.php
index 9460a35dd5bb20c139454184067138da299656a1..859a26c779e75cfea4567391dda61ee855f2677f 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/activate.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/activate.php
@@ -26,7 +26,7 @@
 				<input type="text" name="key" id="key" value="" />
 
 				<p class="submit">
-					<input type="submit" name="submit" value="<?php _e( 'Activate', 'buddypress' ); ?>" />
+					<input type="submit" name="submit" value="<?php esc_attr_e( 'Activate', 'buddypress' ); ?>" />
 				</p>
 
 			</form>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/register.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/register.php
index e619221bd10b580bdfba5de52fe2dc95b9bf4bd0..6624817eedc4dc107d7c37f936346e42bef66390 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/register.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/register.php
@@ -19,7 +19,7 @@
 
 			<?php do_action( 'template_notices' ); ?>
 
-			<p><?php _e( 'Registering for this site is easy, just fill in the fields below and we\'ll get a new account set up for you in no time.', 'buddypress' ); ?></p>
+			<p><?php _e( 'Registering for this site is easy. Just fill in the fields below, and we\'ll get a new account set up for you in no time.', 'buddypress' ); ?></p>
 
 			<?php do_action( 'bp_before_account_details_fields' ); ?>
 
@@ -45,6 +45,8 @@
 				<?php do_action( 'bp_signup_password_confirm_errors' ); ?>
 				<input type="password" name="signup_password_confirm" id="signup_password_confirm" value="" />
 
+				<?php do_action( 'bp_account_details_fields' ); ?>
+
 			</div><!-- #basic-details-section -->
 
 			<?php do_action( 'bp_after_account_details_fields' ); ?>
@@ -60,98 +62,19 @@
 					<h4><?php _e( 'Profile Details', 'buddypress' ); ?></h4>
 
 					<?php /* Use the profile field loop to render input fields for the 'base' profile field group */ ?>
-					<?php if ( bp_is_active( 'xprofile' ) ) : if ( bp_has_profile( 'profile_group_id=1' ) ) : while ( bp_profile_groups() ) : bp_the_profile_group(); ?>
+					<?php if ( bp_is_active( 'xprofile' ) ) : if ( bp_has_profile( array( 'profile_group_id' => 1, 'fetch_field_data' => false ) ) ) : while ( bp_profile_groups() ) : bp_the_profile_group(); ?>
 
 					<?php while ( bp_profile_fields() ) : bp_the_profile_field(); ?>
 
 						<div class="editfield">
 
-							<?php if ( 'textbox' == bp_get_the_profile_field_type() ) : ?>
-
-								<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-								<?php do_action( bp_get_the_profile_field_errors_action() ); ?>
-								<input type="text" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" value="<?php bp_the_profile_field_edit_value(); ?>" />
-
-							<?php endif; ?>
-
-							<?php if ( 'textarea' == bp_get_the_profile_field_type() ) : ?>
-
-								<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-								<?php do_action( bp_get_the_profile_field_errors_action() ); ?>
-								<textarea rows="5" cols="40" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_edit_value(); ?></textarea>
-
-							<?php endif; ?>
-
-							<?php if ( 'selectbox' == bp_get_the_profile_field_type() ) : ?>
-
-								<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-								<?php do_action( bp_get_the_profile_field_errors_action() ); ?>
-								<select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>">
-									<?php bp_the_profile_field_options(); ?>
-								</select>
-
-							<?php endif; ?>
-
-							<?php if ( 'multiselectbox' == bp_get_the_profile_field_type() ) : ?>
-
-								<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-								<?php do_action( bp_get_the_profile_field_errors_action() ); ?>
-								<select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" multiple="multiple">
-									<?php bp_the_profile_field_options(); ?>
-								</select>
-
-							<?php endif; ?>
-
-							<?php if ( 'radio' == bp_get_the_profile_field_type() ) : ?>
-
-								<div class="radio">
-									<span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span>
-
-									<?php do_action( bp_get_the_profile_field_errors_action() ); ?>
-									<?php bp_the_profile_field_options(); ?>
-
-									<?php if ( !bp_get_the_profile_field_is_required() ) : ?>
-										<a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a>
-									<?php endif; ?>
-								</div>
-
-							<?php endif; ?>
-
-							<?php if ( 'checkbox' == bp_get_the_profile_field_type() ) : ?>
-
-								<div class="checkbox">
-									<span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span>
-
-									<?php do_action( bp_get_the_profile_field_errors_action() ); ?>
-									<?php bp_the_profile_field_options(); ?>
-								</div>
-
-							<?php endif; ?>
-
-							<?php if ( 'datebox' == bp_get_the_profile_field_type() ) : ?>
+							<?php
+							$field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() );
+							$field_type->edit_field_html();
 
-								<div class="datebox">
-									<label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-									<?php do_action( bp_get_the_profile_field_errors_action() ); ?>
+							do_action( 'bp_custom_profile_edit_fields_pre_visibility' );
 
-									<select name="<?php bp_the_profile_field_input_name(); ?>_day" id="<?php bp_the_profile_field_input_name(); ?>_day">
-										<?php bp_the_profile_field_options( 'type=day' ); ?>
-									</select>
-
-									<select name="<?php bp_the_profile_field_input_name(); ?>_month" id="<?php bp_the_profile_field_input_name(); ?>_month">
-										<?php bp_the_profile_field_options( 'type=month' ); ?>
-									</select>
-
-									<select name="<?php bp_the_profile_field_input_name(); ?>_year" id="<?php bp_the_profile_field_input_name(); ?>_year">
-										<?php bp_the_profile_field_options( 'type=year' ); ?>
-									</select>
-								</div>
-
-							<?php endif; ?>
-
-							<?php do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); ?>
-
-							<?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?>
+							if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?>
 								<p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>">
 									<?php printf( __( 'This field can be seen by: <span class="current-visibility-level">%s</span>', 'buddypress' ), bp_get_the_profile_field_visibility_level_label() ) ?> <a href="#" class="visibility-toggle-link"><?php _ex( 'Change', 'Change profile field visibility level', 'buddypress' ); ?></a>
 								</p>
@@ -184,6 +107,8 @@
 
 					<?php endwhile; endif; endif; ?>
 
+					<?php do_action( 'bp_signup_profile_fields' ); ?>
+
 				</div><!-- #profile-details-section -->
 
 				<?php do_action( 'bp_after_signup_profile_fields' ); ?>
@@ -223,6 +148,8 @@
 						<label><input type="radio" name="signup_blog_privacy" id="signup_blog_privacy_public" value="public"<?php if ( 'public' == bp_get_signup_blog_privacy_value() || !bp_get_signup_blog_privacy_value() ) : ?> checked="checked"<?php endif; ?> /> <?php _e( 'Yes', 'buddypress' ); ?></label>
 						<label><input type="radio" name="signup_blog_privacy" id="signup_blog_privacy_private" value="private"<?php if ( 'private' == bp_get_signup_blog_privacy_value() ) : ?> checked="checked"<?php endif; ?> /> <?php _e( 'No', 'buddypress' ); ?></label>
 
+						<?php do_action( 'bp_blog_details_fields' ); ?>
+
 					</div>
 
 				</div><!-- #blog-details-section -->
@@ -234,7 +161,7 @@
 			<?php do_action( 'bp_before_registration_submit_buttons' ); ?>
 
 			<div class="submit">
-				<input type="submit" name="signup_submit" id="signup_submit" value="<?php _e( 'Complete Sign Up', 'buddypress' ); ?>" />
+				<input type="submit" name="signup_submit" id="signup_submit" value="<?php esc_attr_e( 'Complete Sign Up', 'buddypress' ); ?>" />
 			</div>
 
 			<?php do_action( 'bp_after_registration_submit_buttons' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/friends.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/friends.php
index 0019fd6f73856e5c44be1d8a53a377ac819e26c6..e49bf5bf6ba10ab948c5a97b584cd9ed9a5f3f75 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/friends.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/friends.php
@@ -23,7 +23,7 @@
 					<option value="newest"><?php _e( 'Newest Registered', 'buddypress' ); ?></option>
 					<option value="alphabetical"><?php _e( 'Alphabetical', 'buddypress' ); ?></option>
 
-					<?php do_action( 'bp_member_blog_order_options' ); ?>
+					<?php do_action( 'bp_member_friends_order_options' ); ?>
 
 				</select>
 			</li>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/groups/invites.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/groups/invites.php
index 4d2047fe77c4a9bdfaf69146bcd3606a482be0e1..613aa6262551d0aaf1a19536a76709990c0ac318 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/groups/invites.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/groups/invites.php
@@ -11,7 +11,7 @@
 					<a href="<?php bp_group_permalink(); ?>"><?php bp_group_avatar( 'type=thumb&width=50&height=50' ); ?></a>
 				</div>
 
-				<h4><a href="<?php bp_group_permalink(); ?>"><?php bp_group_name(); ?></a><span class="small"> - <?php printf( __( '%s members', 'buddypress' ), bp_group_total_members( false ) ); ?></span></h4>
+				<h4><a href="<?php bp_group_permalink(); ?>"><?php bp_group_name(); ?></a><span class="small"> - <?php printf( _n( '1 member', '%d members', bp_get_group_total_members( false ), 'buddypress' ), bp_get_group_total_members( false )  ); ?></span></h4>
 
 				<p class="desc">
 					<?php bp_group_description_excerpt(); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/home.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/home.php
index 72b6d5ade0ff7f0c92a0a4295d3a56706cdb166a..0022cb30f53b8e36cc7c81e3c1ed82eb3e9eddcc 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/home.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/home.php
@@ -45,6 +45,9 @@
 		elseif ( bp_is_user_forums() ) :
 			bp_get_template_part( 'members/single/forums'   );
 
+		elseif ( bp_is_user_notifications() ) :
+			bp_get_template_part( 'members/single/notifications' );
+
 		elseif ( bp_is_user_settings() ) :
 			bp_get_template_part( 'members/single/settings' );
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/member-header.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/member-header.php
index a02511ab41ed46b219271f9c9573da0ed8a32a2f..d7409b935386345140a8a45aba5521c4a8d2cf9f 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/member-header.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/member-header.php
@@ -22,7 +22,7 @@
 <div id="item-header-content">
 
 	<?php if ( bp_is_active( 'activity' ) && bp_activity_do_mentions() ) : ?>
-		<h2 class="user-nicename">@<?php bp_displayed_user_username(); ?></h2>
+		<h2 class="user-nicename">@<?php bp_displayed_user_mentionname(); ?></h2>
 	<?php endif; ?>
 
 	<span class="activity"><?php bp_last_activity( bp_displayed_user_id() ); ?></span>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages.php
index 3990a2be27996d1e2b204142e0aedc301337045c..272c1b6205ab8848d123fb203a5fbf374dc317c3 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages.php
@@ -15,7 +15,7 @@
 		<?php bp_get_options_nav(); ?>
 
 	</ul>
-	
+
 	<?php if ( bp_is_messages_inbox() || bp_is_messages_sentbox() ) : ?>
 
 		<div class="message-search"><?php bp_message_search_form(); ?></div>
@@ -54,7 +54,7 @@ switch ( bp_current_action() ) :
 		do_action( 'bp_before_member_messages_content' ); ?>
 
 		<div class="messages" role="main">
-			<?php bp_get_template_part( 'members/single/messages/notices-loop' );; ?>
+			<?php bp_get_template_part( 'members/single/messages/notices-loop' ); ?>
 		</div><!-- .messages -->
 
 		<?php do_action( 'bp_after_member_messages_content' );
@@ -64,4 +64,4 @@ switch ( bp_current_action() ) :
 	default :
 		bp_get_template_part( 'members/single/plugins' );
 		break;
-endswitch;
\ No newline at end of file
+endswitch;
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/compose.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/compose.php
index cc8076aba4436cc21d72627849d320e58e6a5ddb..4190b8454162a6f53353a4c660608651a79aec93 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/compose.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/compose.php
@@ -25,7 +25,7 @@
 	<?php do_action( 'bp_after_messages_compose_content' ); ?>
 
 	<div class="submit">
-		<input type="submit" value="<?php _e( "Send Message", 'buddypress' ); ?>" name="send" id="send" />
+		<input type="submit" value="<?php esc_attr_e( "Send Message", 'buddypress' ); ?>" name="send" id="send" />
 	</div>
 
 	<?php wp_nonce_field( 'messages_send_message' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php
index 2e721df896ac1f8cca227c8d5d69803c7a873c91..981a8d2397bc99aaec6e24b5d64aa7ed429c5420 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php
@@ -40,7 +40,7 @@
 				<?php endif; ?>
 
 				<td width="50%" class="thread-info">
-					<p><a href="<?php bp_message_thread_view_link(); ?>" title="<?php _e( "View Message", "buddypress" ); ?>"><?php bp_message_thread_subject(); ?></a></p>
+					<p><a href="<?php bp_message_thread_view_link(); ?>" title="<?php esc_attr_e( "View Message", "buddypress" ); ?>"><?php bp_message_thread_subject(); ?></a></p>
 					<p class="thread-excerpt"><?php bp_message_thread_excerpt(); ?></p>
 				</td>
 
@@ -48,7 +48,7 @@
 
 				<td width="13%" class="thread-options">
 					<input type="checkbox" name="message_ids[]" value="<?php bp_message_thread_id(); ?>" />
-					<a class="button confirm" href="<?php bp_message_thread_delete_link(); ?>" title="<?php _e( "Delete Message", "buddypress" ); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a> &nbsp;
+					<a class="button confirm" href="<?php bp_message_thread_delete_link(); ?>" title="<?php esc_attr_e( "Delete Message", "buddypress" ); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a> &nbsp;
 				</td>
 			</tr>
 
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/notices-loop.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/notices-loop.php
index 5733c8b2fc3ff6cdf33e6117456ff8670951dbef..7f7ba2d3d1de3c432bae5300757cfb8bae880de2 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/notices-loop.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/notices-loop.php
@@ -40,7 +40,7 @@
 
 				<td width="10%">
 					<a class="button" href="<?php bp_message_activate_deactivate_link(); ?>" class="confirm"><?php bp_message_activate_deactivate_text(); ?></a>
-					<a class="button" href="<?php bp_message_notice_delete_link(); ?>" class="confirm" title="<?php _e( "Delete Message", "buddypress" ); ?>">x</a>
+					<a class="button" href="<?php bp_message_notice_delete_link(); ?>" class="confirm" title="<?php esc_attr_e( "Delete Message", "buddypress" ); ?>">x</a>
 				</td>
 			</tr>
 		<?php endwhile; ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/single.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/single.php
index 0f0648aa9994dcfe485f1caeb5279c22d2d38c00..09f73bdbe1e8f4f09d53a896425d7a18095d6a41 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/single.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/messages/single.php
@@ -21,7 +21,7 @@
 
 			</span>
 
-			<a class="button confirm" href="<?php bp_the_thread_delete_link(); ?>" title="<?php _e( "Delete Message", "buddypress" ); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a> &nbsp;
+			<a class="button confirm" href="<?php bp_the_thread_delete_link(); ?>" title="<?php esc_attr_e( "Delete Message", "buddypress" ); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a> &nbsp;
 		</p>
 
 		<?php do_action( 'bp_before_message_thread_list' ); ?>
@@ -99,7 +99,7 @@
 					<?php do_action( 'bp_after_message_reply_box' ); ?>
 
 					<div class="submit">
-						<input type="submit" name="send" value="<?php _e( 'Send Reply', 'buddypress' ); ?>" id="send_reply_button"/>
+						<input type="submit" name="send" value="<?php esc_attr_e( 'Send Reply', 'buddypress' ); ?>" id="send_reply_button"/>
 					</div>
 
 					<input type="hidden" id="thread_id" name="thread_id" value="<?php bp_the_thread_id(); ?>" />
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications.php
new file mode 100644
index 0000000000000000000000000000000000000000..c91d118c3901d6af3d9250bd55defb249d894802
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * BuddyPress - Users Notifications
+ *
+ * @package BuddyPress
+ * @subpackage bp-legacy
+ */
+
+?>
+
+<div class="item-list-tabs no-ajax" id="subnav" role="navigation">
+	<ul>
+		<?php bp_get_options_nav(); ?>
+
+		<li id="members-order-select" class="last filter">
+			<?php bp_notifications_sort_order_form(); ?>
+		</li>
+	</ul>
+</div>
+
+<?php
+switch ( bp_current_action() ) :
+
+	// Unread
+	case 'unread' :
+		bp_get_template_part( 'members/single/notifications/unread' );
+		break;
+
+	// Read
+	case 'read' :
+		bp_get_template_part( 'members/single/notifications/read' );
+		break;
+
+	// Any other
+	default :
+		bp_get_template_part( 'members/single/plugins' );
+		break;
+endswitch;
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/feedback-no-notifications.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/feedback-no-notifications.php
new file mode 100644
index 0000000000000000000000000000000000000000..014947bdfb56c6eb43a39240b3f00dff914ccd88
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/feedback-no-notifications.php
@@ -0,0 +1,29 @@
+<div id="message" class="info">
+
+	<?php if ( bp_is_current_action( 'unread' ) ) : ?>
+
+		<?php if ( bp_is_my_profile() ) : ?>
+
+			<p><?php _e( 'You have no unread notifications.', 'buddypress' ); ?></p>
+
+		<?php else : ?>
+
+			<p><?php _e( 'This member has no unread notifications.', 'buddypress' ); ?></p>
+
+		<?php endif; ?>
+			
+	<?php else : ?>
+			
+		<?php if ( bp_is_my_profile() ) : ?>
+
+			<p><?php _e( 'You have no notifications.', 'buddypress' ); ?></p>
+
+		<?php else : ?>
+
+			<p><?php _e( 'This member has no notifications.', 'buddypress' ); ?></p>
+
+		<?php endif; ?>
+
+	<?php endif; ?>
+
+</div>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php
new file mode 100644
index 0000000000000000000000000000000000000000..61e0aea3d18faa723a807f05bfbf2ea57c96aeba
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php
@@ -0,0 +1,25 @@
+<table class="notifications">
+	<thead>
+		<tr>
+			<th class="icon"></th>
+			<th class="title"><?php _e( 'Notification', 'buddypress' ); ?></th>
+			<th class="date"><?php _e( 'Date Received', 'buddypress' ); ?></th>
+			<th class="actions"><?php _e( 'Actions',    'buddypress' ); ?></th>
+		</tr>
+	</thead>
+
+	<tbody>
+
+		<?php while ( bp_the_notifications() ) : bp_the_notification(); ?>
+
+			<tr>
+				<td></td>
+				<td><?php bp_the_notification_description();  ?></td>
+				<td><?php bp_the_notification_time_since();   ?></td>
+				<td><?php bp_the_notification_action_links(); ?></td>
+			</tr>
+
+		<?php endwhile; ?>
+
+	</tbody>
+</table>
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/read.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/read.php
new file mode 100644
index 0000000000000000000000000000000000000000..85fcab77469a5f91c5110d647ccd63b06ff437de
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/read.php
@@ -0,0 +1,29 @@
+<?php if ( bp_has_notifications() ) : ?>
+
+	<div id="pag-top" class="pagination no-ajax">
+		<div class="pag-count" id="notifications-count-top">
+			<?php bp_notifications_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="notifications-pag-top">
+			<?php bp_notifications_pagination_links(); ?>
+		</div>
+	</div>
+
+	<?php bp_get_template_part( 'members/single/notifications/notifications-loop' ); ?>
+
+	<div id="pag-bottom" class="pagination no-ajax">
+		<div class="pag-count" id="notifications-count-bottom">
+			<?php bp_notifications_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="notifications-pag-bottom">
+			<?php bp_notifications_pagination_links(); ?>
+		</div>
+	</div>
+
+<?php else : ?>
+
+	<?php bp_get_template_part( 'members/single/notifications/feedback-no-notifications' ); ?>
+
+<?php endif;
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/unread.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/unread.php
new file mode 100644
index 0000000000000000000000000000000000000000..85fcab77469a5f91c5110d647ccd63b06ff437de
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/unread.php
@@ -0,0 +1,29 @@
+<?php if ( bp_has_notifications() ) : ?>
+
+	<div id="pag-top" class="pagination no-ajax">
+		<div class="pag-count" id="notifications-count-top">
+			<?php bp_notifications_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="notifications-pag-top">
+			<?php bp_notifications_pagination_links(); ?>
+		</div>
+	</div>
+
+	<?php bp_get_template_part( 'members/single/notifications/notifications-loop' ); ?>
+
+	<div id="pag-bottom" class="pagination no-ajax">
+		<div class="pag-count" id="notifications-count-bottom">
+			<?php bp_notifications_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="notifications-pag-bottom">
+			<?php bp_notifications_pagination_links(); ?>
+		</div>
+	</div>
+
+<?php else : ?>
+
+	<?php bp_get_template_part( 'members/single/notifications/feedback-no-notifications' ); ?>
+
+<?php endif;
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/profile/change-avatar.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/profile/change-avatar.php
index 636bc3f61b7403ff1c2bfa3f5b9ef24d5d12c786..e6cd1bec82e54a56ecb5afd9d1b35a023dcade5e 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/profile/change-avatar.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/profile/change-avatar.php
@@ -15,13 +15,13 @@
 
 			<p id="avatar-upload">
 				<input type="file" name="file" id="file" />
-				<input type="submit" name="upload" id="upload" value="<?php _e( 'Upload Image', 'buddypress' ); ?>" />
+				<input type="submit" name="upload" id="upload" value="<?php esc_attr_e( 'Upload Image', 'buddypress' ); ?>" />
 				<input type="hidden" name="action" id="action" value="bp_avatar_upload" />
 			</p>
 
 			<?php if ( bp_get_user_has_avatar() ) : ?>
 				<p><?php _e( "If you'd like to delete your current avatar but not upload a new one, please use the delete avatar button.", 'buddypress' ); ?></p>
-				<p><a class="button edit" href="<?php bp_avatar_delete_link(); ?>" title="<?php _e( 'Delete Avatar', 'buddypress' ); ?>"><?php _e( 'Delete My Avatar', 'buddypress' ); ?></a></p>
+				<p><a class="button edit" href="<?php bp_avatar_delete_link(); ?>" title="<?php esc_attr_e( 'Delete Avatar', 'buddypress' ); ?>"><?php _e( 'Delete My Avatar', 'buddypress' ); ?></a></p>
 			<?php endif; ?>
 
 		<?php endif; ?>
@@ -30,13 +30,13 @@
 
 			<h5><?php _e( 'Crop Your New Avatar', 'buddypress' ); ?></h5>
 
-			<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php _e( 'Avatar to crop', 'buddypress' ); ?>" />
+			<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php esc_attr_e( 'Avatar to crop', 'buddypress' ); ?>" />
 
 			<div id="avatar-crop-pane">
-				<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php _e( 'Avatar preview', 'buddypress' ); ?>" />
+				<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php esc_attr_e( 'Avatar preview', 'buddypress' ); ?>" />
 			</div>
 
-			<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php _e( 'Crop Image', 'buddypress' ); ?>" />
+			<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php esc_attr_e( 'Crop Image', 'buddypress' ); ?>" />
 
 			<input type="hidden" name="image_src" id="image_src" value="<?php bp_avatar_to_crop_src(); ?>" />
 			<input type="hidden" id="x" name="x" />
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/profile/edit.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/profile/edit.php
index c4def0ba7540fe1f4d6fd10e113ab4c50035465b..a20c079ad5c2d19900da22a34a2af2c885be94d0 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/profile/edit.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/profile/edit.php
@@ -21,99 +21,12 @@ if ( bp_has_profile( 'profile_group_id=' . bp_get_current_profile_group_id() ) )
 
 			<div<?php bp_field_css_class( 'editfield' ); ?>>
 
-				<?php if ( 'textbox' == bp_get_the_profile_field_type() ) : ?>
+				<?php
+				$field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() );
+				$field_type->edit_field_html();
 
-					<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-					<input type="text" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" value="<?php bp_the_profile_field_edit_value(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>/>
-
-				<?php endif; ?>
-
-				<?php if ( 'textarea' == bp_get_the_profile_field_type() ) : ?>
-
-					<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-					<textarea rows="5" cols="40" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>><?php bp_the_profile_field_edit_value(); ?></textarea>
-
-				<?php endif; ?>
-
-				<?php if ( 'selectbox' == bp_get_the_profile_field_type() ) : ?>
-
-					<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-					<select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>>
-						<?php bp_the_profile_field_options(); ?>
-					</select>
-
-				<?php endif; ?>
-
-				<?php if ( 'multiselectbox' == bp_get_the_profile_field_type() ) : ?>
-
-					<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-					<select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" multiple="multiple" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>>
-
-						<?php bp_the_profile_field_options(); ?>
-
-					</select>
-
-					<?php if ( !bp_get_the_profile_field_is_required() ) : ?>
-
-						<a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a>
-
-					<?php endif; ?>
-
-				<?php endif; ?>
-
-				<?php if ( 'radio' == bp_get_the_profile_field_type() ) : ?>
-
-					<div class="radio">
-						<span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span>
-
-						<?php bp_the_profile_field_options(); ?>
-
-						<?php if ( !bp_get_the_profile_field_is_required() ) : ?>
-
-							<a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a>
-
-						<?php endif; ?>
-					</div>
-
-				<?php endif; ?>
-
-				<?php if ( 'checkbox' == bp_get_the_profile_field_type() ) : ?>
-
-					<div class="checkbox">
-						<span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span>
-
-						<?php bp_the_profile_field_options(); ?>
-					</div>
-
-				<?php endif; ?>
-
-				<?php if ( 'datebox' == bp_get_the_profile_field_type() ) : ?>
-
-					<div class="datebox">
-						<label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
-
-						<select name="<?php bp_the_profile_field_input_name(); ?>_day" id="<?php bp_the_profile_field_input_name(); ?>_day" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>>
-
-							<?php bp_the_profile_field_options( 'type=day' ); ?>
-
-						</select>
-
-						<select name="<?php bp_the_profile_field_input_name(); ?>_month" id="<?php bp_the_profile_field_input_name(); ?>_month" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>>
-
-							<?php bp_the_profile_field_options( 'type=month' ); ?>
-
-						</select>
-
-						<select name="<?php bp_the_profile_field_input_name(); ?>_year" id="<?php bp_the_profile_field_input_name(); ?>_year" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>>
-
-							<?php bp_the_profile_field_options( 'type=year' ); ?>
-
-						</select>
-					</div>
-
-				<?php endif; ?>
-
-				<?php do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); ?>
+				do_action( 'bp_custom_profile_edit_fields_pre_visibility' );
+				?>
 
 				<?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?>
 					<p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>">
@@ -145,7 +58,7 @@ if ( bp_has_profile( 'profile_group_id=' . bp_get_current_profile_group_id() ) )
 	<?php do_action( 'bp_after_profile_field_content' ); ?>
 
 	<div class="submit">
-		<input type="submit" name="profile-group-edit-submit" id="profile-group-edit-submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?> " />
+		<input type="submit" name="profile-group-edit-submit" id="profile-group-edit-submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?> " />
 	</div>
 
 	<input type="hidden" name="field_ids" id="field_ids" value="<?php bp_the_profile_group_field_ids(); ?>" />
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings.php
index b10256b92366535ccb5c942fdfd01d6f23d400f3..58e5dfceb48da63a8c16dda6907cb1fd8391a138 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings.php
@@ -34,7 +34,10 @@ switch ( bp_current_action() ) :
 	case 'general'        :
 		bp_get_template_part( 'members/single/settings/general'        );
 		break;
+	case 'profile'        :
+		bp_get_template_part( 'members/single/settings/profile'        );
+		break;
 	default:
 		bp_get_template_part( 'members/single/plugins'                 );
 		break;
-endswitch;
\ No newline at end of file
+endswitch;
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/capabilities.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/capabilities.php
index 660f08fa83f188b0e96b07dc65ffae5b3686bc58..c472db1e3e2e6de118ba4d403226363f56afcd16 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/capabilities.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/capabilities.php
@@ -10,7 +10,7 @@
 	</label>
 
 	<div class="submit">
-		<input type="submit" value="<?php _e( 'Save', 'buddypress' ); ?>" id="capabilities-submit" name="capabilities-submit" />
+		<input type="submit" value="<?php esc_attr_e( 'Save', 'buddypress' ); ?>" id="capabilities-submit" name="capabilities-submit" />
 	</div>
 
 	<?php do_action( 'bp_members_capabilities_account_after_submit' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/delete-account.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/delete-account.php
index 4503a7be09e9e2af6995228b5163d54e95253263..d347e95bc6d26433189837a72cb892c16f353ea3 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/delete-account.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/delete-account.php
@@ -24,7 +24,7 @@
 	</label>
 
 	<div class="submit">
-		<input type="submit" disabled="disabled" value="<?php _e( 'Delete Account', 'buddypress' ); ?>" id="delete-account-button" name="delete-account-button" />
+		<input type="submit" disabled="disabled" value="<?php esc_attr_e( 'Delete Account', 'buddypress' ); ?>" id="delete-account-button" name="delete-account-button" />
 	</div>
 
 	<?php do_action( 'bp_members_delete_account_after_submit' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/general.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/general.php
index ecaf9447034f0e2fa5eeac98c13099332965d1fd..d5058fc128203743d3472d5430966343825f117d 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/general.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/general.php
@@ -5,7 +5,7 @@
 	<?php if ( !is_super_admin() ) : ?>
 
 		<label for="pwd"><?php _e( 'Current Password <span>(required to update email or change current password)</span>', 'buddypress' ); ?></label>
-		<input type="password" name="pwd" id="pwd" size="16" value="" class="settings-input small" /> &nbsp;<a href="<?php echo wp_lostpassword_url(); ?>" title="<?php _e( 'Password Lost and Found', 'buddypress' ); ?>"><?php _e( 'Lost your password?', 'buddypress' ); ?></a>
+		<input type="password" name="pwd" id="pwd" size="16" value="" class="settings-input small" /> &nbsp;<a href="<?php echo wp_lostpassword_url(); ?>" title="<?php esc_attr_e( 'Password Lost and Found', 'buddypress' ); ?>"><?php _e( 'Lost your password?', 'buddypress' ); ?></a>
 
 	<?php endif; ?>
 
@@ -19,7 +19,7 @@
 	<?php do_action( 'bp_core_general_settings_before_submit' ); ?>
 
 	<div class="submit">
-		<input type="submit" name="submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
+		<input type="submit" name="submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
 	</div>
 
 	<?php do_action( 'bp_core_general_settings_after_submit' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/notifications.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/notifications.php
index 53a496d1e6fe7490fe3069e4f475b4beba802bcd..3af9f5635861d4e30fe83d86417801d8db1d4e0d 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/notifications.php
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/notifications.php
@@ -1,14 +1,14 @@
 <?php do_action( 'bp_before_member_settings_template' ); ?>
 
 <form action="<?php echo bp_displayed_user_domain() . bp_get_settings_slug() . '/notifications'; ?>" method="post" class="standard-form" id="settings-form">
-	<p><?php _e( 'Send a notification by email when:', 'buddypress' ); ?></p>
+	<p><?php _e( 'Send an email notice when:', 'buddypress' ); ?></p>
 
 	<?php do_action( 'bp_notification_settings' ); ?>
 
 	<?php do_action( 'bp_members_notification_settings_before_submit' ); ?>
 
 	<div class="submit">
-		<input type="submit" name="submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
+		<input type="submit" name="submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
 	</div>
 
 	<?php do_action( 'bp_members_notification_settings_after_submit' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/profile.php b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/profile.php
new file mode 100644
index 0000000000000000000000000000000000000000..4e5f1b293dbfe384b07e0264e4075c94240152c6
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/settings/profile.php
@@ -0,0 +1,53 @@
+<?php do_action( 'bp_before_member_settings_template' ); ?>
+
+<form action="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_settings_slug() . '/profile' ); ?>" method="post" class="standard-form" id="settings-form">
+
+	<?php if ( bp_xprofile_get_settings_fields() ) : ?>
+
+		<?php while ( bp_profile_groups() ) : bp_the_profile_group(); ?>
+
+			<?php if ( bp_profile_fields() ) : ?>
+
+				<table class="profile-settings" id="xprofile-settings-<?php bp_the_profile_group_slug(); ?>">
+					<thead>
+						<tr>
+							<th class="title field-group-name"><?php bp_the_profile_group_name(); ?></th>
+							<th class="title"><?php _e( 'Visibility', 'buddypress' ); ?></th>
+						</tr>
+					</thead>
+
+					<tbody>
+
+						<?php while ( bp_profile_fields() ) : bp_the_profile_field(); ?>
+
+							<tr <?php bp_field_css_class(); ?>>
+								<td class="field-name"><?php bp_the_profile_field_name(); ?></td>
+								<td class="field-visibility"><?php bp_profile_settings_visibility_select(); ?></td>
+							</tr>
+
+						<?php endwhile; ?>
+
+					</tbody>
+				</table>
+
+			<?php endif; ?>
+
+		<?php endwhile; ?>
+
+	<?php endif; ?>
+
+	<?php do_action( 'bp_core_xprofile_settings_before_submit' ); ?>
+
+	<div class="submit">
+		<input id="submit" type="submit" name="xprofile-settings-submit" value="<?php esc_attr_e( 'Save Settings', 'buddypress' ); ?>" class="auto" />
+	</div>
+
+	<?php do_action( 'bp_core_xprofile_settings_after_submit' ); ?>
+
+	<?php wp_nonce_field( 'bp_xprofile_settings' ); ?>
+
+	<input type="hidden" name="field_ids" id="field_ids" value="<?php bp_the_profile_group_field_ids(); ?>" />
+
+</form>
+
+<?php do_action( 'bp_after_member_settings_template' );
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/css/buddypress-rtl.css b/wp-content/plugins/buddypress/bp-templates/bp-legacy/css/buddypress-rtl.css
index d5ba9af11043cf0fe21ce79252523fcf5d9d3f42..3dd99d0d88799d768c93da4ebc5eab134f665d60 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/css/buddypress-rtl.css
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/css/buddypress-rtl.css
@@ -84,6 +84,9 @@ Hello, this is the BuddyPress Legacy stylesheet.
 	margin: 0 !important;
 	padding: 0 !important;
 }
+#buddypress .clear {
+	clear: right;
+}
 
 /*--------------------------------------------------------------
 3.0 - BuddyPress
@@ -1376,6 +1379,13 @@ body.register #buddypress div.page ul {
 #buddypress .field-visibility-settings-toggle {
 	font-style: italic;
 }
+#buddypress .field-visibility-settings .radio {
+	list-style: none;
+	margin-bottom: 0;
+}
+#buddypress .field-visibility select {
+	margin: 0;
+}
 
 /*--------------------------------------------------------------
 3.11 - Widgets
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/css/buddypress.css b/wp-content/plugins/buddypress/bp-templates/bp-legacy/css/buddypress.css
index 6b41a6ffc4b5275fa28853d056289d6d625d536d..36a16c7eb7ae54a7b10af54369f1962734dc203d 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/css/buddypress.css
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/css/buddypress.css
@@ -84,6 +84,9 @@ Hello, this is the BuddyPress Legacy stylesheet.
 	margin: 0 !important;
 	padding: 0 !important;
 }
+#buddypress .clear {
+	clear: left;
+}
 
 /*--------------------------------------------------------------
 3.0 - BuddyPress
@@ -290,14 +293,16 @@ body.activity-permalink #buddypress .activity-content blockquote {
 	margin-left: 1em;
 	white-space: nowrap;
 }
-#buddypress .activity-list li.load-more {
+#buddypress .activity-list li.load-more,
+#buddypress .activity-list li.load-newest {
 	background: #f0f0f0;
 	font-size: 110%;
 	margin: 15px 0;
 	padding: 10px 15px;
 	text-align: center;
 }
-#buddypress .activity-list li.load-more a {
+#buddypress .activity-list li.load-more a,
+#buddypress .activity-list li.load-newest a {
 	color: #4D4D4D;
 }
 
@@ -486,7 +491,8 @@ body.activity-permalink #buddypress div.activity-comments div.acomment-content {
 	float: right;
 	margin: -39px 0 0 0;
 }
-#buddypress div.dir-search input[type=text] {
+#buddypress div.dir-search input[type=text],
+#buddypress li.groups-members-search input[type=text] {
 	font-size: 90%;
 	padding: 1px 3px;
 }
@@ -581,7 +587,9 @@ body.activity-permalink #buddypress div.activity-comments div.acomment-content {
 #buddypress .standard-form select,
 #buddypress .standard-form input[type=password],
 #buddypress .dir-search input[type=search],
-#buddypress .dir-search input[type=text] {
+#buddypress .dir-search input[type=text],
+#buddypress .groups-members-search input[type=search],
+#buddypress .groups-members-search input[type=text] {
 	border: 1px solid #ccc;
 	background: #fafafa;
 	border-radius: 0;
@@ -602,8 +610,8 @@ body.activity-permalink #buddypress div.activity-comments div.acomment-content {
 	font-weight: bold;
 	margin: 15px 0 5px 0;
 }
-#buddypress .standard-form div.checkbox label,
-#buddypress .standard-form div.radio label {
+#buddypress .standard-form div.checkbox label:nth-child(n+2),
+#buddypress .standard-form div.radio div label {
 	color: #888;
 	font-size: 100%;
 	font-weight: normal;
@@ -759,12 +767,21 @@ a.bp-title-button {
 
 #buddypress form.standard-form .main-column ul#friend-list {
 	clear:none;
+	float: left;
 }
 
 #buddypress form.standard-form .main-column ul#friend-list h4 {
 	clear:none;
 }
 
+/* Overrides for embedded WP editors */
+#buddypress .wp-editor-wrap a.button,
+#buddypress .wp-editor-wrap button,
+#buddypress .wp-editor-wrap input[type=submit],
+#buddypress .wp-editor-wrap input[type=button],
+#buddypress .wp-editor-wrap input[type=reset] {
+	padding: 0 10px 1px;
+}
 /*--------------------------------------------------------------
 3.6 - Ajax Loading
 --------------------------------------------------------------*/
@@ -879,10 +896,22 @@ a.bp-title-button {
 	margin: 20px 0 0 0;
 	padding: 1px 0 0 0;
 }
-#buddypress table {
+#buddypress table.notifications,
+#buddypress table.notifications-settings,
+#buddypress table.profile-settings,
+#buddypress table.profile-fields,
+#buddypress table.wp-profile-fields,
+#buddypress table.messages-notices,
+#buddypress table.forum {
 	width: 100%;
 }
-#buddypress table thead tr {
+#buddypress table.notifications thead tr,
+#buddypress table.notifications-settings thead tr,
+#buddypress table.profile-settings thead tr,
+#buddypress table.profile-fields thead tr,
+#buddypress table.wp-profile-fields thead tr,
+#buddypress table.messages-notices thead tr,
+#buddypress table.forum thead tr {
 	background: #eaeaea;
 }
 #buddypress table#message-threads {
@@ -902,12 +931,28 @@ a.bp-title-button {
 #buddypress table.profile-fields p:last-child {
 	margin-top: 0;
 }
-#buddypress table tr td,
-#buddypress table tr th {
+#buddypress table.notifications tr td,
+#buddypress table.notifications-settings tr td,
+#buddypress table.profile-settings tr td,
+#buddypress table.profile-fields tr td,
+#buddypress table.wp-profile-fields tr td,
+#buddypress table.messages-notices tr td,
+#buddypress table.forum tr td,
+#buddypress table.notifications tr th,
+#buddypress table.notifications-settings tr th,
+#buddypress table.profile-fields tr th,
+#buddypress table.wp-profile-fields tr th,
+#buddypress table.messages-notices tr th,
+#buddypress table.forum tr th {
 	padding: 8px;
 	vertical-align: middle;
 }
-#buddypress table tr td.label {
+#buddypress table.notifications tr td.label,
+#buddypress table.notifications-settings tr td.label,
+#buddypress table.profile-fields tr td.label,
+#buddypress table.wp-profile-fields tr td.label,
+#buddypress table.messages-notices tr td.label,
+#buddypress table.forum tr td.label {
 	border-right: 1px solid #eaeaea;
 	font-weight: bold;
 	width: 25%;
@@ -923,7 +968,13 @@ a.bp-title-button {
 #buddypress table.forum td {
 	text-align: center;
 }
-#buddypress table tr.alt td {
+#buddypress table.notifications tr.alt td,
+#buddypress table.notifications-settings tr.alt td,
+#buddypress table.profile-settings tr.alt td,
+#buddypress table.profile-fields tr.alt td,
+#buddypress table.wp-profile-fields tr.alt td,
+#buddypress table.messages-notices tr.alt td,
+#buddypress table.forum tr.alt td {
 	background: #f5f5f5;
 }
 #buddypress table.notification-settings {
@@ -933,11 +984,14 @@ a.bp-title-button {
 #buddypress #groups-notification-settings {
 	margin-bottom: 0;
 }
+#buddypress table.notifications th.icon,
+#buddypress table.notifications td:first-child,
 #buddypress table.notification-settings th.icon,
 #buddypress table.notification-settings td:first-child {
 	display: none;
 }
-#buddypress table.notification-settings th.title {
+#buddypress table.notification-settings th.title,
+#buddypress table.profile-settings th.title {
 	width: 80%;
 }
 #buddypress table.notification-settings .yes,
@@ -1379,6 +1433,13 @@ body.register #buddypress div.page ul {
 #buddypress .field-visibility-settings-toggle {
 	font-style: italic;
 }
+#buddypress .field-visibility-settings .radio {
+	list-style: none;
+	margin-bottom: 0;
+}
+#buddypress .field-visibility select {
+	margin: 0;
+}
 
 /*--------------------------------------------------------------
 3.11 - Widgets
@@ -1427,6 +1488,32 @@ body.register #buddypress div.page ul {
 	overflow: hidden;
 }
 
+.widget.buddypress #bp-login-widget-form label {
+	display: block;
+	margin: 1rem 0 .5rem;
+}
+
+.widget.buddypress #bp-login-widget-form #bp-login-widget-submit {
+	margin-right: 10px;
+}
+
+.widget.buddypress .bp-login-widget-user-avatar {
+	float: left;
+	width: 60px;
+}
+
+.widget.buddypress .bp-login-widget-user-links > div {
+	padding-left: 60px;
+}
+
+.widget.buddypress .bp-login-widget-user-links > div {
+	margin-bottom: .5rem;
+}
+
+.widget.buddypress .bp-login-widget-user-links > div.bp-login-widget-user-link a {
+	font-weight: bold;
+}
+
 /*--------------------------------------------------------------
 4.0 - Media Queries
 --------------------------------------------------------------*/
diff --git a/wp-content/plugins/buddypress/bp-templates/bp-legacy/js/buddypress.js b/wp-content/plugins/buddypress/bp-templates/bp-legacy/js/buddypress.js
index 11099409f19907298aa6b1dd22ee5c0f1a34e595..67ecbbe5dc2bbf0f1b3187c42a55049eb932531a 100644
--- a/wp-content/plugins/buddypress/bp-templates/bp-legacy/js/buddypress.js
+++ b/wp-content/plugins/buddypress/bp-templates/bp-legacy/js/buddypress.js
@@ -4,6 +4,10 @@ var jq = jQuery;
 // Global variable to prevent multiple AJAX requests
 var bp_ajax_request = null;
 
+// Global variables to temporarly store newest activities
+var newest_activities = '';
+var activity_last_recorded  = 0;
+
 jq(document).ready( function() {
 	/**** Page Load Actions *******************************************************/
 
@@ -17,7 +21,7 @@ jq(document).ready( function() {
 	bp_init_activity();
 
 	/* Object filter and scope set. */
-	var objects = [ 'members', 'groups', 'blogs', 'forums' ];
+	var objects = [ 'members', 'groups', 'blogs', 'forums', 'group_members' ];
 	bp_init_objects( objects );
 
 	/* @mention Compose Scrolling */
@@ -48,29 +52,46 @@ jq(document).ready( function() {
 			height:'50px'
 		});
 		jq("#aw-whats-new-submit").prop("disabled", false);
-		
+
 		var $whats_new_form = jq("form#whats-new-form");
 		if ( $whats_new_form.hasClass("submitted") ) {
-			$whats_new_form.removeClass("submitted");	
+			$whats_new_form.removeClass("submitted");
+		}
+
+		// Return to the 'All Members' tab and 'Everything' filter,
+		// to avoid inconsistencies with the heartbeat integration
+		var $activity_all = jq( '#activity-all' );
+		if ( $activity_all.length  ) {
+			if ( ! $activity_all.hasClass( 'selected' ) ) {
+				// reset to everyting
+				jq( '#activity-filter-select select' ).val( '-1' );
+				$activity_all.children( 'a' ).trigger( "click" );
+			} else if ( '-1' != jq( '#activity-filter-select select' ).val() ) {
+				jq( '#activity-filter-select select' ).val( '-1' );
+				jq( '#activity-filter-select select' ).trigger( 'change' );
+			}
 		}
 	});
 
 	/* On blur, shrink if it's empty */
 	$whats_new.blur( function(){
-		if (!this.value.match(/\S+/)) {
-			this.value = "";
-			jq("#whats-new-options").animate({
-				height:'40px'
-			});
-			jq("form#whats-new-form textarea").animate({
-				height:'20px'
-			});
-			jq("#aw-whats-new-submit").prop("disabled", true);
+		if ( document.activeElement != this ) {
+			if (!this.value.match(/\S+/)) {
+				this.value = "";
+				jq("#whats-new-options").animate({
+					height:'40px'
+				});
+				jq("form#whats-new-form textarea").animate({
+					height:'20px'
+				});
+				jq("#aw-whats-new-submit").prop("disabled", true);
+			}
 		}
 	});
 
 	/* New posts */
 	jq("#aw-whats-new-submit").on( 'click', function() {
+		var last_date_recorded = 0;
 		var button = jq(this);
 		var form = button.closest("form#whats-new-form");
 
@@ -89,6 +110,23 @@ jq(document).ready( function() {
 		var object = '';
 		var item_id = jq("#whats-new-post-in").val();
 		var content = jq("#whats-new").val();
+		var firstrow = jq( '#buddypress ul.activity-list li' ).first();
+		var activity_row = firstrow;
+		var timestamp = null;
+
+		// Checks if at least one activity exists
+		if ( firstrow.length ) {
+
+			if ( activity_row.hasClass( 'load-newest' ) ) {
+				activity_row = firstrow.next();
+			}
+			
+			timestamp = activity_row.prop( 'class' ).match( /date-recorded-([0-9]+)/ );
+		}
+ 		
+ 		if ( timestamp ) {
+			last_date_recorded = timestamp[1];
+		}
 
 		/* Set object for non-profile posts */
 		if ( item_id > 0 ) {
@@ -102,6 +140,7 @@ jq(document).ready( function() {
 			'content': content,
 			'object': object,
 			'item_id': item_id,
+			'since': last_date_recorded,
 			'_bp_as_nonce': jq('#_bp_as_nonce').val() || ''
 		},
 		function(response) {
@@ -123,8 +162,13 @@ jq(document).ready( function() {
 					jq("div.activity").append( '<ul id="activity-stream" class="activity-list item-list">' );
 				}
 
+				if ( firstrow.hasClass( 'load-newest' ) )
+					firstrow.remove();
+
 				jq("#activity-stream").prepend(response);
-				jq("#activity-stream li:first").addClass('new-update just-posted');
+
+				if ( ! last_date_recorded )
+					jq("#activity-stream li:first").addClass('new-update just-posted');
 
 				if ( 0 != jq("#latest-update").length ) {
 					var l = jq("#activity-stream li.new-update .activity-content .activity-inner p").html();
@@ -147,6 +191,10 @@ jq(document).ready( function() {
 				jq("li.new-update").hide().slideDown( 300 );
 				jq("li.new-update").removeClass( 'new-update' );
 				jq("#whats-new").val('');
+
+				// reset vars to get newest activities
+				newest_activities = '';
+				activity_last_recorded  = 0;
 			}
 
 			jq("#whats-new-options").animate({
@@ -255,7 +303,7 @@ jq(document).ready( function() {
 				}
 
 				if ( 'activity-favorites' == jq( '.item-list-tabs li.selected').attr('id') )
-					target.parent().parent().parent().slideUp(100);
+					target.closest( '.activity-item' ).slideUp( 100 );
 			});
 
 			return false;
@@ -267,6 +315,7 @@ jq(document).ready( function() {
 			var id        = li.attr('id').substr( 9, li.attr('id').length );
 			var link_href = target.attr('href');
 			var nonce     = link_href.split('_wpnonce=');
+			var timestamp = li.prop( 'class' ).match( /date-recorded-([0-9]+)/ );
 
 			nonce = nonce[1];
 
@@ -285,6 +334,12 @@ jq(document).ready( function() {
 					li.children('#message').hide().fadeIn(300);
 				} else {
 					li.slideUp(300);
+
+					// reset vars to get newest activities
+					if ( timestamp && activity_last_recorded == timestamp[1] ) {
+						newest_activities = '';
+						activity_last_recorded  = 0;
+					}
 				}
 			});
 
@@ -293,7 +348,8 @@ jq(document).ready( function() {
 
 		// Spam activity stream items
 		if ( target.hasClass( 'spam-activity' ) ) {
-			var li = target.parents( 'div.activity ul li' );
+			var li        = target.parents( 'div.activity ul li' );
+			var timestamp = li.prop( 'class' ).match( /date-recorded-([0-9]+)/ );
 			target.addClass( 'loading' );
 
 			jq.post( ajaxurl, {
@@ -309,6 +365,11 @@ jq(document).ready( function() {
 					li.children( '#message' ).hide().fadeIn(300);
 				} else {
 					li.slideUp( 300 );
+					// reset vars to get newest activities
+					if ( timestamp && activity_last_recorded == timestamp[1] ) {
+						newest_activities = '';
+						activity_last_recorded  = 0;
+					}
 				}
 			});
 
@@ -327,7 +388,7 @@ jq(document).ready( function() {
 			var oldest_page = ( jq.cookie('bp-activity-oldestpage') * 1 ) + 1;
 
 			var just_posted = [];
-			
+
 			jq('.activity-list li.just-posted').each( function(){
 				just_posted.push( jq(this).attr('id').replace( 'activity-','' ) );
 			});
@@ -351,10 +412,38 @@ jq(document).ready( function() {
 
 			return false;
 		}
+
+		/* Load newest updates at the top of the list */
+		if ( target.parent().hasClass('load-newest') ) {
+
+			event.preventDefault();
+
+			target.parent().hide();
+
+			/** 
+			 * If a plugin is updating the recorded_date of an activity 
+			 * it will be loaded as a new one. We need to look in the
+			 * stream and eventually remove similar ids to avoid "double".
+			 */
+			activity_html = jq.parseHTML( newest_activities );
+			
+			jq.each( activity_html, function( i, el ){
+				if( 'LI' == el.nodeName && jq(el).hasClass( 'just-posted' ) ) {
+					if( jq( '#' + jq(el).attr( 'id' ) ).length )
+						jq( '#' + jq(el).attr( 'id' ) ).remove();
+				}
+			} );
+
+			// Now the stream is cleaned, prepend newest
+			jq( '#buddypress ul.activity-list' ).prepend( newest_activities );
+
+			// reset the newest activities now they're displayed
+			newest_activities = '';
+		}
 	});
 
 	// Activity "Read More" links
-	jq('.activity-read-more a').on('click', function(event) {
+	jq('div.activity').on('click', '.activity-read-more a', function(event) {
 		var target = jq(event.target);
 		var link_id = target.parent().attr('id').split('-');
 		var a_id = link_id[3];
@@ -555,7 +644,7 @@ jq(document).ready( function() {
 					var count_span = jq('#' + comment_li.parents('#activity-stream > li').attr('id') + ' a.acomment-reply span');
 					var new_count = count_span.html() - ( 1 + child_count );
 					count_span.html(new_count);
-					
+
 					// Change the 'Show all x comments' text
 					var show_all_a = comment_li.siblings('.show-all').find('a');
 					if ( show_all_a ) {
@@ -629,7 +718,7 @@ jq(document).ready( function() {
 			return false;
 		}
 
-		// Canceling an activity comment	
+		// Canceling an activity comment
 		if ( target.hasClass( 'ac-reply-cancel' ) ) {
 			jq(target).closest('.ac-form').slideUp( 200 );
 			return false;
@@ -663,7 +752,7 @@ jq(document).ready( function() {
 	/**** Directory Search ****************************************************/
 
 	/* The search form on all directory pages */
-	jq('.dir-search').on( 'click', function(event) {
+	jq( '.dir-search, .groups-members-search' ).on( 'click', function(event) {
 		if ( jq(this).hasClass('no-ajax') )
 			return;
 
@@ -672,8 +761,15 @@ jq(document).ready( function() {
 		if ( target.attr('type') == 'submit' ) {
 			var css_id = jq('.item-list-tabs li.selected').attr('id').split( '-' );
 			var object = css_id[0];
+			var template = null;
 
-			bp_filter_request( object, jq.cookie('bp-' + object + '-filter'), jq.cookie('bp-' + object + '-scope') , 'div.' + object, target.parent().children('label').children('input').val(), 1, jq.cookie('bp-' + object + '-extras') );
+			// The Group Members page specifies its own template
+			if ( 'members' == object && 'groups' == css_id[1] ) {
+				object = 'group_members';
+				template = 'groups/single/members';
+			}
+
+			bp_filter_request( object, jq.cookie('bp-' + object + '-filter'), jq.cookie('bp-' + object + '-scope') , 'div.' + object, target.parent().children('label').children('input').val(), 1, jq.cookie('bp-' + object + '-extras'), null, template );
 
 			return false;
 		}
@@ -717,14 +813,28 @@ jq(document).ready( function() {
 		var scope = css_id[1];
 		var filter = jq(this).val();
 		var search_terms = false;
+		var template = null;
 
 		if ( jq('.dir-search input').length )
 			search_terms = jq('.dir-search input').val();
 
+		// The Group Members page has a different selector for its
+		// search terms box
+		var $gm_search = jq( '.groups-members-search input' );
+		if ( $gm_search.length ) {
+			search_terms = $gm_search.val();
+		}
+
+		// On the Groups Members page, we specify a template
+		if ( 'members' == object && 'groups' == scope ) {
+			object = 'group_members';
+			template = 'groups/single/members';
+		}
+
 		if ( 'friends' == object )
 			object = 'members';
 
-		bp_filter_request( object, filter, scope, 'div.' + object, search_terms, 1, jq.cookie('bp-' + object + '-extras') );
+		bp_filter_request( object, filter, scope, 'div.' + object, search_terms, 1, jq.cookie('bp-' + object + '-extras'), null, template );
 
 		return false;
 	});
@@ -745,22 +855,45 @@ jq(document).ready( function() {
 			else
 				var el = jq('li.filter select');
 
-			var page_number = 1;
 			var css_id = el.attr('id').split( '-' );
 			var object = css_id[0];
 			var search_terms = false;
+			var pagination_id = jq(target).closest('.pagination-links').attr('id');
+			var template = null;
+
+			var page_number = target.attr('href').split( '=' );
+			page_number = page_number[1];
 
+			// Search terms
 			if ( jq('div.dir-search input').length )
 				search_terms = jq('.dir-search input').val();
 
-			if ( jq(target).hasClass('next') )
-				var page_number = Number( jq('.pagination span.current').html() ) + 1;
-			else if ( jq(target).hasClass('prev') )
-				var page_number = Number( jq('.pagination span.current').html() ) - 1;
-			else
-				var page_number = Number( jq(target).html() );
+			// The Group Members page has a different selector for
+			// its search terms box
+			var $gm_search = jq( '.groups-members-search input' );
+			if ( $gm_search.length ) {
+				search_terms = $gm_search.val();
+			}
 
-			bp_filter_request( object, jq.cookie('bp-' + object + '-filter'), jq.cookie('bp-' + object + '-scope'), 'div.' + object, search_terms, page_number, jq.cookie('bp-' + object + '-extras') );
+			// On the Groups Members page, we specify a template
+			if ( 'members' == object && 'groups' == css_id[1] ) {
+				object = 'group_members';
+				template = 'groups/single/members';
+			}
+
+			// On the Admin > Requests page, we need to reset the object,
+			// since "admin" isn't specific enough
+			if ( 'admin' == object && jq( 'body' ).hasClass( 'membership-requests' ) ) {
+				object = 'requests';
+			}
+
+			if ( pagination_id.indexOf( 'pag-bottom' ) !== -1 ) {
+				var caller = 'pag-bottom';
+			} else {
+				var caller = null;
+			}
+
+			bp_filter_request( object, jq.cookie('bp-' + object + '-filter'), jq.cookie('bp-' + object + '-scope'), 'div.' + object, search_terms, page_number, jq.cookie('bp-' + object + '-extras'), caller, template );
 
 			return false;
 		}
@@ -802,17 +935,30 @@ jq(document).ready( function() {
 	/** Invite Friends Interface ****************************************/
 
 	/* Select a user from the list of friends and add them to the invite list */
-	jq("#invite-list input").on( 'click', function() {
+	jq("#send-invite-form").on( 'click', '#invite-list input', function() {
+		// invites-loop template contains a div with the .invite class
+		// We use the existence of this div to check for old- vs new-
+		// style templates.
+		var invites_new_template = jq( "#send-invite-form > .invite" ).length;
+
 		jq('.ajax-loader').toggle();
 
+		// Dim the form until the response arrives
+		if ( invites_new_template ) {
+			jq( this ).parents( 'ul' ).find( 'input' ).prop( 'disabled', true );
+		}
+
 		var friend_id = jq(this).val();
 
-		if ( jq(this).prop('checked') == true )
+		if ( jq(this).prop('checked') == true ) {
 			var friend_action = 'invite';
-		else
+		} else {
 			var friend_action = 'uninvite';
+		}
 
-		jq('.item-list-tabs li.selected').addClass('loading');
+		if ( ! invites_new_template ) {
+			jq( '.item-list-tabs li.selected' ).addClass( 'loading' );
+		}
 
 		jq.post( ajaxurl, {
 			action: 'groups_invite_user',
@@ -824,23 +970,37 @@ jq(document).ready( function() {
 		},
 		function(response)
 		{
-			if ( jq("#message") )
+			if ( jq("#message") ) {
 				jq("#message").hide();
+			}
 
-			jq('.ajax-loader').toggle();
+			if ( invites_new_template ) {
+				// With new-style templates, we refresh the
+				// entire list
+				bp_filter_request( 'invite', 'bp-invite-filter', 'bp-invite-scope', 'div.invite', false, 1, '', '', '' );
+			} else {
+				// Old-style templates manipulate only the
+				// single invitation element
+				jq('.ajax-loader').toggle();
+
+				if ( friend_action == 'invite' ) {
+					jq('#friend-list').append(response);
+				} else if ( friend_action == 'uninvite' ) {
+					jq('#friend-list li#uid-' + friend_id).remove();
+				}
 
-			if ( friend_action == 'invite' ) {
-				jq('#friend-list').append(response);
-			} else if ( friend_action == 'uninvite' ) {
-				jq('#friend-list li#uid-' + friend_id).remove();
+				jq('.item-list-tabs li.selected').removeClass('loading');
 			}
-
-			jq('.item-list-tabs li.selected').removeClass('loading');
 		});
 	});
 
 	/* Remove a user from the list of users to invite to a group */
-	jq("#friend-list").on('click', 'li a.remove', function() {
+	jq("#send-invite-form").on('click', 'a.remove', function() {
+		// invites-loop template contains a div with the .invite class
+		// We use the existence of this div to check for old- vs new-
+		// style templates.
+		var invites_new_template = jq("#send-invite-form > .invite").length;
+
 		jq('.ajax-loader').toggle();
 
 		var friend_id = jq(this).attr('id');
@@ -857,36 +1017,40 @@ jq(document).ready( function() {
 		},
 		function(response)
 		{
-			jq('.ajax-loader').toggle();
-			jq('#friend-list #uid-' + friend_id).remove();
-			jq('#invite-list #f-' + friend_id).prop('checked', false);
+			if ( invites_new_template ) {
+				// With new-style templates, we refresh the
+				// entire list
+				bp_filter_request( 'invite', 'bp-invite-filter', 'bp-invite-scope', 'div.invite', false, 1, '', '', '' );
+			} else {
+				// Old-style templates manipulate only the
+				// single invitation element
+				jq('.ajax-loader').toggle();
+				jq('#friend-list #uid-' + friend_id).remove();
+				jq('#invite-list #f-' + friend_id).prop('checked', false);
+			}
 		});
 
 		return false;
 	});
 
 	/** Profile Visibility Settings *********************************/
-	jq('.field-visibility-settings').hide();
-	jq('.visibility-toggle-link').on( 'click', function() {
-		var toggle_div = jq(this).parent();
-
-		jq(toggle_div).fadeOut( 600, function(){
-			jq(toggle_div).siblings('.field-visibility-settings').slideDown(400);
-		});
+	jq( '.visibility-toggle-link' ).on( 'click', function( event ) {
+		event.preventDefault();
 
-		return false;
+		jq( this ).parent().hide()
+			.siblings( '.field-visibility-settings' ).show();
 	} );
 
-	jq('.field-visibility-settings-close').on( 'click', function() {
-		var settings_div = jq(this).parent();
-		var vis_setting_text = settings_div.find('input:checked').parent().text();
+	jq( '.field-visibility-settings-close' ).on( 'click', function( event ) {
+		event.preventDefault();
 
-		settings_div.slideUp( 400, function() {
-			settings_div.siblings('.field-visibility-settings-toggle').fadeIn(800);
-			settings_div.siblings('.field-visibility-settings-toggle').children('.current-visibility-level').html(vis_setting_text);
-		} );
+		var settings_div = jq( this ).parent(),
+			vis_setting_text = settings_div.find( 'input:checked' ).parent().text();
 
-		return false;
+		settings_div.hide()
+			.siblings( '.field-visibility-settings-toggle' )
+				.children( '.current-visibility-level' ).text( vis_setting_text ).end()
+			.show();
 	} );
 
 	jq("#profile-edit-form input:not(:submit), #profile-edit-form textarea, #profile-edit-form select, #signup_form input:not(:submit), #signup_form textarea, #signup_form select").change( function() {
@@ -895,7 +1059,7 @@ jq(document).ready( function() {
 		jq('#profile-edit-form input:submit, #signup_form input:submit').on( 'click', function() {
 			shouldconfirm = false;
 		});
-		
+
 		window.onbeforeunload = function(e) {
 			if ( shouldconfirm ) {
 				return BP_DTheme.unsaved_changes;
@@ -959,7 +1123,7 @@ jq(document).ready( function() {
 	});
 
 	/* Add / Remove friendship buttons */
-	jq('#members-dir-list').on('click', '.friendship-button a', function() {
+	jq( '#members-dir-list, #members-group-list' ).on('click', '.friendship-button a', function() {
 		jq(this).parent().addClass('loading');
 		var fid = jq(this).attr('id');
 		fid = fid.split('-');
@@ -1009,6 +1173,13 @@ jq(document).ready( function() {
 
 	/** Group Join / Leave Buttons **************************************/
 
+	// Confirmation when clicking Leave Group in group headers
+	jq('#buddypress').on('click', '.group-button .leave-group', function() {
+		if ( false == confirm( BP_DTheme.leave_group_confirm ) ) {
+			return false;
+		}
+	});
+
 	jq('#groups-dir-list').on('click', '.group-button a', function() {
 		var gid = jq(this).parent().attr('id');
 		gid = gid.split('-');
@@ -1021,6 +1192,12 @@ jq(document).ready( function() {
 
 		var thelink = jq(this);
 
+		// Leave Group confirmation within directories - must intercept
+		// AJAX request
+		if ( thelink.hasClass( 'leave-group' ) && false == confirm( BP_DTheme.leave_group_confirm ) ) {
+			return false;
+		}
+
 		jq.post( ajaxurl, {
 			action: 'joinleave_group',
 			'cookie': bp_get_cookies(),
@@ -1031,14 +1208,41 @@ jq(document).ready( function() {
 		{
 			var parentdiv = thelink.parent();
 
-			if ( !jq('body.directory').length )
+			// user groups page
+			if ( ! jq('body.directory').length ) {
 				location.href = location.href;
-			else {
+
+			// groups directory
+			} else {
 				jq(parentdiv).fadeOut(200,
 					function() {
 						parentdiv.fadeIn(200).html(response);
+
+						var mygroups = jq('#groups-personal span');
+						var add      = 1;
+
+						if( thelink.hasClass( 'leave-group' ) ) {
+							// hidden groups slide up
+							if ( parentdiv.hasClass( 'hidden' ) ) {
+								parentdiv.closest('li').slideUp( 200 );
+							}
+
+							add = 0;
+						} else if ( thelink.hasClass( 'request-membership' ) ) {
+							add = false;
+						}
+
+						// change the "My Groups" value
+						if ( mygroups.length && add !== false ) {
+							if ( add ) {
+								mygroups.text( ( mygroups.text() >> 0 ) + 1 );
+							} else {
+								mygroups.text( ( mygroups.text() >> 0 ) - 1 );
+							}
+						}
+
 					}
-					);
+				);
 			}
 		});
 		return false;
@@ -1164,36 +1368,38 @@ jq(document).ready( function() {
 	});
 
 	/* Selecting unread and read messages in inbox */
-	jq("#message-type-select").change(
-		function() {
-			var selection = jq("#message-type-select").val();
-			var checkboxes = jq("td input[type='checkbox']");
-			checkboxes.each( function(i) {
-				checkboxes[i].checked = "";
-			});
+	jq( 'body.messages #item-body div.messages' ).on( 'change', '#message-type-select', function() {
+		var selection = this.value;
+		var checkboxes = jq( "td input[type='checkbox']" );
 
-			switch(selection) {
-				case 'unread':
-					var checkboxes = jq("tr.unread td input[type='checkbox']");
-					break;
-				case 'read':
-					var checkboxes = jq("tr.read td input[type='checkbox']");
-					break;
-			}
-			if ( selection != '' ) {
-				checkboxes.each( function(i) {
-					checkboxes[i].checked = "checked";
-				});
-			} else {
-				checkboxes.each( function(i) {
-					checkboxes[i].checked = "";
-				});
-			}
+		checkboxes.each( function(i) {
+			checkboxes[i].checked = "";
+		});
+
+		var checked_value = "checked";
+		switch ( selection ) {
+			case 'unread' :
+				checkboxes = jq("tr.unread td input[type='checkbox']");
+				break;
+			case 'read' :
+				checkboxes = jq("tr.read td input[type='checkbox']");
+				break;
+			case '' :
+				checked_value = "";
+				break;
 		}
-	);
+
+		checkboxes.each( function(i) {
+			checkboxes[i].checked = checked_value;
+		});
+	});
 
 	/* Bulk delete messages */
-	jq("#delete_inbox_messages, #delete_sentbox_messages").on( 'click', function() {
+	jq( 'body.messages #item-body div.messages' ).on( 'click', '.messages-options-nav a', function() {
+		if ( -1 == jq.inArray( this.id, Array( 'delete_sentbox_messages', 'delete_inbox_messages' ) ) ) {
+			return;
+		}
+
 		checkboxes_tosend = '';
 		checkboxes = jq("#message-threads tr td input[type='checkbox']");
 
@@ -1220,14 +1426,19 @@ jq(document).ready( function() {
 				jq('#message-threads').before( '<div id="message" class="updated"><p>' + response + '</p></div>' );
 
 				jq(checkboxes).each( function(i) {
-					if( jq(this).is(':checked') )
+					if( jq(this).is(':checked') ) {
+						// We need to uncheck because message is only hidden
+						// Otherwise, AJAX will be fired again with same data
+						jq(this).attr( 'checked', false );
 						jq(this).parent().parent().fadeOut(150);
+					}
 				});
 			}
 
 			jq('#message').hide().slideDown(150);
 			jq("#delete_inbox_messages, #delete_sentbox_messages").removeClass('loading');
 		});
+
 		return false;
 	});
 
@@ -1287,11 +1498,63 @@ jq(document).ready( function() {
 			} );
 		});
 	});
-	
+
 	/* if js is enabled then replace the no-js class by a js one */
 	if( jq('body').hasClass('no-js') )
 		jq('body').attr('class', jq('body').attr('class').replace( /no-js/,'js' ) );
+
+	/** Activity HeartBeat ************************************************/
+
+	// Set the interval and the namespace event
+	if ( typeof wp != 'undefined' && typeof wp.heartbeat != 'undefined' && typeof BP_DTheme.pulse != 'undefined' ) {
+
+		wp.heartbeat.interval( Number( BP_DTheme.pulse ) );
+
+		jq.fn.extend({
+			'heartbeat-send': function() {
+			return this.bind( 'heartbeat-send.buddypress' );
+	        },
+	    });
+
+	}
+
+	// Set the last id to request after
+	jq( document ).on( 'heartbeat-send.buddypress', function( e, data ) {
 		
+		firstrow = 0;
+
+		// First row is default latest activity id
+		if ( jq( '#buddypress ul.activity-list li' ).first().prop( 'id' ) ) {
+			// getting the timestamp
+			timestamp = jq( '#buddypress ul.activity-list li' ).first().prop( 'class' ).match( /date-recorded-([0-9]+)/ );
+
+			if ( timestamp ) {
+				firstrow = timestamp[1];
+			}
+		}
+
+		if ( 0 == activity_last_recorded || Number( firstrow ) > activity_last_recorded )
+			activity_last_recorded = Number( firstrow );
+
+		data['bp_activity_last_recorded'] = activity_last_recorded;
+	});
+
+	// Increment newest_activities and activity_last_recorded if data has been returned
+	jq( document ).on( 'heartbeat-tick', function( e, data ) {
+
+		// Only proceed if we have newest activities
+		if ( ! data['bp_activity_newest_activities'] ) {
+			return;
+		}
+
+		newest_activities = data['bp_activity_newest_activities']['activities'] + newest_activities;
+		activity_last_recorded  = Number( data['bp_activity_newest_activities']['last_recorded'] );
+
+		if ( jq( '#buddypress ul.activity-list li' ).first().hasClass( 'load-newest' ) )
+			return;
+
+		jq( '#buddypress ul.activity-list' ).prepend( '<li class="load-newest"><a href="#newest">' + BP_DTheme.newest + '</a></li>' );
+	});
 });
 
 /* Setup activity scope and filter based on the current cookie settings. */
@@ -1329,7 +1592,7 @@ function bp_init_objects(objects) {
 }
 
 /* Filter the current content list (groups/members/blogs/topics) */
-function bp_filter_request( object, filter, scope, target, search_terms, page, extras ) {
+function bp_filter_request( object, filter, scope, target, search_terms, page, extras, caller, template ) {
 	if ( 'activity' == object )
 		return false;
 
@@ -1358,8 +1621,9 @@ function bp_filter_request( object, filter, scope, target, search_terms, page, e
 	jq('.item-list-tabs li.selected').addClass('loading');
 	jq('.item-list-tabs select option[value="' + filter + '"]').prop( 'selected', true );
 
-	if ( 'friends' == object )
+	if ( 'friends' == object || 'group_members' == object ) {
 		object = 'members';
+	}
 
 	if ( bp_ajax_request )
 		bp_ajax_request.abort();
@@ -1372,14 +1636,28 @@ function bp_filter_request( object, filter, scope, target, search_terms, page, e
 		'search_terms': search_terms,
 		'scope': scope,
 		'page': page,
-		'extras': extras
+		'extras': extras,
+		'template': template
 	},
 	function(response)
 	{
-		jq(target).fadeOut( 100, function() {
-			jq(this).html(response);
-			jq(this).fadeIn(100);
-		});
+		/* animate to top if called from bottom pagination */
+		if ( caller == 'pag-bottom' && jq('#subnav').length ) {
+			var top = jq('#subnav').parent();
+			jq('html,body').animate({scrollTop: top.offset().top}, 'slow', function() {
+				jq(target).fadeOut( 100, function() {
+					jq(this).html(response);
+					jq(this).fadeIn(100);
+			 	});
+			});
+
+		} else {
+			jq(target).fadeOut( 100, function() {
+				jq(this).html(response);
+				jq(this).fadeIn(100);
+		 	});
+		}
+
 		jq('.item-list-tabs li.selected').removeClass('loading');
 	});
 }
@@ -1464,7 +1742,7 @@ function bp_legacy_theme_hide_comments() {
 				jq(this).addClass('hidden');
 				jq(this).toggle();
 
-				if ( !i ) 
+				if ( !i )
 					jq(this).before( '<li class="show-all"><a href="#' + parent_li.attr('id') + '/show-all/" title="' + BP_DTheme.show_all_comments + '">' + BP_DTheme.show_x_comments.replace( '%d', comment_count ) + '</a></li>' );
 			}
 		});
@@ -1488,24 +1766,33 @@ function checkAll() {
 	}
 }
 
-function clear(container) {
-	if( !document.getElementById(container) ) return;
+/**
+ * Deselects any select options or input options for the specified field element.
+ *
+ * @param {String} container HTML ID of the field
+ * @since BuddyPress (1.2.0)
+ */
+function clear( container ) {
+	container = document.getElementById( container );
+	if ( ! container ) {
+		return;
+	}
 
-	var container = document.getElementById(container);
+	var radioButtons = container.getElementsByTagName( 'INPUT' ),
+		options = container.getElementsByTagName( 'OPTION' ),
+		i       = 0;
 
-	if ( radioButtons = container.getElementsByTagName('INPUT') ) {
-		for(var i=0; i<radioButtons.length; i++) {
+	if ( radioButtons ) {
+		for ( i = 0; i < radioButtons.length; i++ ) {
 			radioButtons[i].checked = '';
 		}
 	}
 
-	if ( options = container.getElementsByTagName('OPTION') ) {
-		for(var i=0; i<options.length; i++) {
+	if ( options ) {
+		for ( i = 0; i < options.length; i++ ) {
 			options[i].selected = false;
 		}
 	}
-
-	return;
 }
 
 /* Returns a querystring of BP cookies (cookies beginning with 'bp-') */
@@ -1520,7 +1807,7 @@ function bp_get_cookies() {
 	for (var i = 0; i < allCookies.length; i++) {
 		var cookie    = allCookies[i];
 		var delimiter = cookie.indexOf("=");
-		var name      = unescape( cookie.slice(0, delimiter) ).trim();
+		var name      = jq.trim( unescape( cookie.slice(0, delimiter) ) );
 		var value     = unescape( cookie.slice(delimiter + 1) );
 
 		// if BP cookie, store it
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/ajax.php b/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/ajax.php
index c6bab0183df90a4c69caf8e38e3b22c48af53bc5..3bf6dd1b69ed87b7900897590e432373b3bcd4e4 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/ajax.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/ajax.php
@@ -352,7 +352,7 @@ function bp_dtheme_new_activity_comment() {
 	 * have the new template) will still work.
 	 */
 	if ( empty( $template ) )
-		$template = BP_PLUGIN_DIR . '/bp-themes/bp-default/activity/comment.php';
+		$template = buddypress()->plugin_dir . '/bp-themes/bp-default/activity/comment.php';
 
 	load_template( $template, false );
 
@@ -568,9 +568,25 @@ function bp_dtheme_ajax_invite_user() {
 	if ( ! friends_check_friendship( bp_loggedin_user_id(), $_POST['friend_id'] ) )
 		return;
 
+	$group_id = (int) $_POST['group_id'];
+	$friend_id = (int) $_POST['friend_id'];
+
 	if ( 'invite' == $_POST['friend_action'] ) {
-		if ( ! groups_invite_user( array( 'user_id' => $_POST['friend_id'], 'group_id' => $_POST['group_id'] ) ) )
+		$group = groups_get_group( $group_id );
+
+		// Users who have previously requested membership do not need
+		// another invitation created for them
+		if ( BP_Groups_Member::check_for_membership_request( $friend_id, $group_id ) ) {
+			$user_status = 'is_pending';
+
+		// Create the user invitation
+		} else if ( groups_invite_user( array( 'user_id' => $friend_id, 'group_id' => $group_id ) ) ) {
+			$user_status = 'is_invited';
+
+		// Miscellaneous failure
+		} else {
 			return;
+		}
 
 		$user = new BP_Core_User( $_POST['friend_id'] );
 
@@ -581,12 +597,25 @@ function bp_dtheme_ajax_invite_user() {
 		echo '<div class="action">
 				<a class="button remove" href="' . wp_nonce_url( bp_loggedin_user_domain() . bp_get_groups_slug() . '/' . $_POST['group_id'] . '/invites/remove/' . $user->id, 'groups_invite_uninvite_user' ) . '" id="uid-' . esc_attr( $user->id ) . '">' . __( 'Remove Invite', 'buddypress' ) . '</a>
 			  </div>';
+
+		if ( 'is_pending' == $user_status ) {
+			echo '<p class="description">' . sprintf( __( '%s has previously requested to join this group. Sending an invitation will automatically add the member to the group.', 'buddypress' ), $user->user_link ) . '</p>';
+		}
+
 		echo '</li>';
 		exit;
 
 	} elseif ( 'uninvite' == $_POST['friend_action'] ) {
-		if ( ! groups_uninvite_user( $_POST['friend_id'], $_POST['group_id'] ) )
+		// Users who have previously requested membership should not
+		// have their requests deleted on the "uninvite" action
+		if ( BP_Groups_Member::check_for_membership_request( $friend_id, $group_id ) ) {
 			return;
+		}
+
+		// Remove the unsent invitation
+		if ( ! groups_uninvite_user( $friend_id, $group_id ) ) {
+			return;
+		}
 
 		exit;
 
@@ -716,12 +745,27 @@ function bp_dtheme_ajax_joinleave_group() {
 			}
 
 		} elseif ( 'private' == $group->status ) {
-			check_ajax_referer( 'groups_request_membership' );
 
-			if ( ! groups_send_membership_request( bp_loggedin_user_id(), $group->id ) ) {
-				_e( 'Error requesting membership', 'buddypress' );
+			// If the user has already been invited, then this is
+			// an Accept Invitation button
+			if ( groups_check_user_has_invite( bp_loggedin_user_id(), $group->id ) ) {
+				check_ajax_referer( 'groups_accept_invite' );
+
+				if ( ! groups_accept_invite( bp_loggedin_user_id(), $group->id ) ) {
+					_e( 'Error requesting membership', 'buddypress' );
+				} else {
+					echo '<a id="group-' . esc_attr( $group->id ) . '" class="leave-group" rel="leave" title="' . __( 'Leave Group', 'buddypress' ) . '" href="' . wp_nonce_url( bp_get_group_permalink( $group ) . 'leave-group', 'groups_leave_group' ) . '">' . __( 'Leave Group', 'buddypress' ) . '</a>';
+				}
+
+			// Otherwise, it's a Request Membership button
 			} else {
-				echo '<a id="group-' . esc_attr( $group->id ) . '" class="membership-requested" rel="membership-requested" title="' . __( 'Membership Requested', 'buddypress' ) . '" href="' . bp_get_group_permalink( $group ) . '">' . __( 'Membership Requested', 'buddypress' ) . '</a>';
+				check_ajax_referer( 'groups_request_membership' );
+
+				if ( ! groups_send_membership_request( bp_loggedin_user_id(), $group->id ) ) {
+					_e( 'Error requesting membership', 'buddypress' );
+				} else {
+					echo '<a id="group-' . esc_attr( $group->id ) . '" class="membership-requested" rel="membership-requested" title="' . __( 'Membership Requested', 'buddypress' ) . '" href="' . bp_get_group_permalink( $group ) . '">' . __( 'Membership Requested', 'buddypress' ) . '</a>';
+				}
 			}
 		}
 
@@ -938,7 +982,8 @@ function bp_dtheme_ajax_messages_autocomplete_results() {
 			}
 
 			if ( bp_is_username_compatibility_mode() ) {
-				$username = $ud->user_login;
+				// Sanitize for spaces
+				$username = urlencode( $ud->user_login );
 			} else {
 				$username = $ud->user_nicename;
 			}
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/css/default.css b/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/css/default.css
index 88da968cb9b8fa722449a6e41b608bb1e8e5d71b..8d1b6aa3a4ce4c73c2883d7730674ac69750c1d2 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/css/default.css
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/css/default.css
@@ -1953,7 +1953,8 @@ table.forum td {
 table tr.alt td {
 	background: #f5f5f5;
 }
-table.notification-settings {
+table.notification-settings,
+table.profile-settings {
 	margin-bottom: 20px;
 	text-align: left;
 }
@@ -1964,7 +1965,8 @@ table.notification-settings th.icon,
 table.notification-settings td:first-child {
 	display: none;
 }
-table.notification-settings th.title {
+table.notification-settings th.title,
+table.profile-settings th.title {
 	width: 80%;
 }
 table.notification-settings .yes,
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/global.js b/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/global.js
index 706e8048cd876812372627da9ac35204891cb9c4..97322e8db9fed8074bc45862abfca72732ce9482 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/global.js
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/global.js
@@ -349,7 +349,7 @@ jq(document).ready( function() {
 	});
 
 	// Activity "Read More" links
-	jq('.activity-read-more a').on('click', function(event) {
+	jq('div.activity').on('click', '.activity-read-more a', function(event) {
 		var target = jq(event.target);
 		var link_id = target.parent().attr('id').split('-');
 		var a_id = link_id[3];
@@ -735,6 +735,7 @@ jq(document).ready( function() {
 			var css_id = el.attr('id').split( '-' );
 			var object = css_id[0];
 			var search_terms = false;
+			var pagination_id = jq(target).closest('.pagination-links').attr('id');
 
 			if ( jq('div.dir-search input').length )
 				search_terms = jq('.dir-search input').val();
@@ -745,8 +746,14 @@ jq(document).ready( function() {
 				var page_number = Number( jq('.pagination span.current').html() ) - 1;
 			else
 				var page_number = Number( jq(target).html() );
+			
+			if ( pagination_id.indexOf( 'pag-bottom' ) !== -1 ) {
+				var caller = 'pag-bottom';
+			} else {
+				var caller = null;
+			}
 
-			bp_filter_request( object, jq.cookie('bp-' + object + '-filter'), jq.cookie('bp-' + object + '-scope'), 'div.' + object, search_terms, page_number, jq.cookie('bp-' + object + '-extras') );
+			bp_filter_request( object, jq.cookie('bp-' + object + '-filter'), jq.cookie('bp-' + object + '-scope'), 'div.' + object, search_terms, page_number, jq.cookie('bp-' + object + '-extras'), caller );
 
 			return false;
 		}
@@ -1015,14 +1022,41 @@ jq(document).ready( function() {
 		{
 			var parentdiv = thelink.parent();
 
-			if ( !jq('body.directory').length )
+			// user groups page
+			if ( ! jq('body.directory').length ) {
 				location.href = location.href;
-			else {
+
+			// groups directory
+			} else {
 				jq(parentdiv).fadeOut(200,
 					function() {
 						parentdiv.fadeIn(200).html(response);
+
+						var mygroups = jq('#groups-personal span');
+						var add      = 1;
+
+						if( thelink.hasClass( 'leave-group' ) ) {
+							// hidden groups slide up
+							if ( parentdiv.hasClass( 'hidden' ) ) {
+								parentdiv.closest('li').slideUp( 200 );
+							}
+
+							add = 0;
+						} else if ( thelink.hasClass( 'request-membership' ) ) {
+							add = false;
+						}
+
+						// change the "My Groups" value
+						if ( add !== false && mygroups.length ) {
+							if ( add ) {
+								mygroups.text( ( mygroups.text() >> 0 ) + 1 );
+							} else {
+								mygroups.text( ( mygroups.text() >> 0 ) - 1 );
+							}
+						}
+
 					}
-					);
+				);
 			}
 		});
 		return false;
@@ -1148,40 +1182,42 @@ jq(document).ready( function() {
 	});
 
 	/* Selecting unread and read messages in inbox */
-	jq("select#message-type-select").change(
-		function() {
-			var selection = jq("select#message-type-select").val();
-			var checkboxes = jq("td input[type='checkbox']");
-			checkboxes.each( function(i) {
-				checkboxes[i].checked = "";
-			});
+	jq( 'body.messages #item-body div.messages' ).on( 'change', '#message-type-select', function() {
+		var selection = this.value;
+		var checkboxes = jq( "td input[type='checkbox']" );
 
-			switch(selection) {
-				case 'unread':
-					var checkboxes = jq("tr.unread td input[type='checkbox']");
-					break;
-				case 'read':
-					var checkboxes = jq("tr.read td input[type='checkbox']");
-					break;
-			}
-			if ( selection != '' ) {
-				checkboxes.each( function(i) {
-					checkboxes[i].checked = "checked";
-				});
-			} else {
-				checkboxes.each( function(i) {
-					checkboxes[i].checked = "";
-				});
-			}
+		checkboxes.each( function(i) {
+			checkboxes[i].checked = "";
+		});
+
+		var checked_value = "checked";
+		switch ( selection ) {
+			case 'unread' :
+				checkboxes = jq("tr.unread td input[type='checkbox']");
+				break;
+			case 'read' :
+				checkboxes = jq("tr.read td input[type='checkbox']");
+				break;
+			case '' :
+				checked_value = "";
+				break;
 		}
-	);
 
+		checkboxes.each( function(i) {
+			checkboxes[i].checked = checked_value;
+		});
+	});
+	
 	/* Bulk delete messages */
-	jq("a#delete_inbox_messages, a#delete_sentbox_messages").click( function() {
+	jq( 'body.messages #item-body div.messages' ).on( 'click', '.messages-options-nav a', function() {
+		if ( -1 == jq.inArray( this.id ), Array( 'delete_sentbox_messages', 'delete_inbox_messages' ) ) {
+			return;
+		}
+		
 		checkboxes_tosend = '';
 		checkboxes = jq("#message-threads tr td input[type='checkbox']");
 
-		jq('div#message').remove();
+		jq('#message').remove();
 		jq(this).addClass('loading');
 
 		jq(checkboxes).each( function(i) {
@@ -1193,7 +1229,7 @@ jq(document).ready( function() {
 			jq(this).removeClass('loading');
 			return false;
 		}
-
+		
 		jq.post( ajaxurl, {
 			action: 'messages_delete',
 			'thread_ids': checkboxes_tosend
@@ -1204,14 +1240,19 @@ jq(document).ready( function() {
 				jq('#message-threads').before( '<div id="message" class="updated"><p>' + response + '</p></div>' );
 
 				jq(checkboxes).each( function(i) {
-					if( jq(this).is(':checked') )
+					if( jq(this).is(':checked') ) {
+						// We need to uncheck because message is only hidden
+						// Otherwise, AJAX will be fired again with same data 
+						jq(this).attr( 'checked', false );
 						jq(this).parent().parent().fadeOut(150);
+					}
 				});
 			}
 
-			jq('div#message').hide().slideDown(150);
-			jq("a#delete_inbox_messages, a#delete_sentbox_messages").removeClass('loading');
+			jq('#message').hide().slideDown(150);
+			jq("#delete_inbox_messages, #delete_sentbox_messages").removeClass('loading');
 		});
+
 		return false;
 	});
 
@@ -1308,7 +1349,7 @@ function bp_init_objects(objects) {
 }
 
 /* Filter the current content list (groups/members/blogs/topics) */
-function bp_filter_request( object, filter, scope, target, search_terms, page, extras ) {
+function bp_filter_request( object, filter, scope, target, search_terms, page, extras, caller ) {
 	if ( 'activity' == object )
 		return false;
 
@@ -1355,10 +1396,23 @@ function bp_filter_request( object, filter, scope, target, search_terms, page, e
 	},
 	function(response)
 	{
-		jq(target).fadeOut( 100, function() {
-			jq(this).html(response);
-			jq(this).fadeIn(100);
-		});
+		/* animate to top if called from bottom pagination */
+		if ( caller == 'pag-bottom' && jq('#subnav').length ) {
+			var top = jq('#subnav').parent();
+			jq('html,body').animate({scrollTop: top.offset().top}, 'slow', function() {
+				jq(target).fadeOut( 100, function() {
+					jq(this).html(response);
+					jq(this).fadeIn(100);
+			 	});
+			});	
+
+		} else {
+			jq(target).fadeOut( 100, function() {
+				jq(this).html(response);
+				jq(this).fadeIn(100);
+		 	});
+		}
+
 		jq('.item-list-tabs li.selected').removeClass('loading');
 	});
 }
@@ -1499,7 +1553,7 @@ function bp_get_cookies() {
 	for (var i = 0; i < allCookies.length; i++) {
 		var cookie    = allCookies[i];
 		var delimiter = cookie.indexOf("=");
-		var name      = unescape( cookie.slice(0, delimiter) ).trim();
+		var name      = jq.trim( unescape( cookie.slice(0, delimiter) ) );
 		var value     = unescape( cookie.slice(delimiter + 1) );
 
 		// if BP cookie, store it
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/activity/activity-loop.php b/wp-content/plugins/buddypress/bp-themes/bp-default/activity/activity-loop.php
index 52a5c0e60d66215f0cfb6db298095fc86d9a6eb8..26581a4b2a9aa044c86fcd18f0d70538824fc774 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/activity/activity-loop.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/activity/activity-loop.php
@@ -59,8 +59,12 @@
 
 <?php do_action( 'bp_after_activity_loop' ); ?>
 
-<form action="" name="activity-loop-form" id="activity-loop-form" method="post">
+<?php if ( empty( $_POST['page'] ) ) : ?>
 
-	<?php wp_nonce_field( 'activity_filter', '_wpnonce_activity_filter' ); ?>
+	<form action="" name="activity-loop-form" id="activity-loop-form" method="post">
 
-</form>
\ No newline at end of file
+		<?php wp_nonce_field( 'activity_filter', '_wpnonce_activity_filter' ); ?>
+
+	</form>
+
+<?php endif; ?>
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/activity/entry.php b/wp-content/plugins/buddypress/bp-themes/bp-default/activity/entry.php
index e32c716636d3b34e9a863dd4db11d7e22dba19ef..44a665a07efd0bb8a17130bff785fec1a186a1bc 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/activity/entry.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/activity/entry.php
@@ -34,7 +34,7 @@
 		<?php if ( 'activity_comment' == bp_get_activity_type() ) : ?>
 
 			<div class="activity-inreplyto">
-				<strong><?php _e( 'In reply to: ', 'buddypress' ); ?></strong><?php bp_activity_parent_content(); ?> <a href="<?php bp_activity_thread_permalink(); ?>" class="view" title="<?php _e( 'View Thread / Permalink', 'buddypress' ); ?>"><?php _e( 'View', 'buddypress' ); ?></a>
+				<strong><?php _e( 'In reply to: ', 'buddypress' ); ?></strong><?php bp_activity_parent_content(); ?> <a href="<?php bp_activity_thread_permalink(); ?>" class="view" title="<?php esc_attr_e( 'View Thread / Permalink', 'buddypress' ); ?>"><?php _e( 'View', 'buddypress' ); ?></a>
 			</div>
 
 		<?php endif; ?>
@@ -87,7 +87,7 @@
 
 	<?php do_action( 'bp_before_activity_entry_comments' ); ?>
 
-	<?php if ( ( is_user_logged_in() && bp_activity_can_comment() ) || bp_activity_get_comment_count() ) : ?>
+	<?php if ( ( is_user_logged_in() && bp_activity_can_comment() ) || bp_is_single_activity() ) : ?>
 
 		<div class="activity-comments">
 
@@ -101,7 +101,7 @@
 						<div class="ac-textarea">
 							<textarea id="ac-input-<?php bp_activity_id(); ?>" class="ac-input" name="ac_input_<?php bp_activity_id(); ?>"></textarea>
 						</div>
-						<input type="submit" name="ac_form_submit" value="<?php _e( 'Post', 'buddypress' ); ?>" /> &nbsp; <?php _e( 'or press esc to cancel.', 'buddypress' ); ?>
+						<input type="submit" name="ac_form_submit" value="<?php esc_attr_e( 'Post', 'buddypress' ); ?>" /> &nbsp; <?php _e( 'or press esc to cancel.', 'buddypress' ); ?>
 						<input type="hidden" name="comment_form_id" value="<?php bp_activity_id(); ?>" />
 					</div>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/activity/index.php b/wp-content/plugins/buddypress/bp-themes/bp-default/activity/index.php
index f943edb805c899ffd16c4e2eccbde2f3737908ff..eecd17ada8ac091afc1ad47de5bf3a58f99a060c 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/activity/index.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/activity/index.php
@@ -36,7 +36,7 @@ get_header( 'buddypress' ); ?>
 				<ul>
 					<?php do_action( 'bp_before_activity_type_tab_all' ); ?>
 
-					<li class="selected" id="activity-all"><a href="<?php bp_activity_directory_permalink(); ?>" title="<?php _e( 'The public activity for everyone on this site.', 'buddypress' ); ?>"><?php printf( __( 'All Members <span>%s</span>', 'buddypress' ), bp_get_total_member_count() ); ?></a></li>
+					<li class="selected" id="activity-all"><a href="<?php bp_activity_directory_permalink(); ?>" title="<?php esc_attr_e( 'The public activity for everyone on this site.', 'buddypress' ); ?>"><?php printf( __( 'All Members <span>%s</span>', 'buddypress' ), bp_get_total_member_count() ); ?></a></li>
 
 					<?php if ( is_user_logged_in() ) : ?>
 
@@ -46,7 +46,7 @@ get_header( 'buddypress' ); ?>
 
 							<?php if ( bp_get_total_friend_count( bp_loggedin_user_id() ) ) : ?>
 
-								<li id="activity-friends"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() . '/'; ?>" title="<?php _e( 'The activity of my friends only.', 'buddypress' ); ?>"><?php printf( __( 'My Friends <span>%s</span>', 'buddypress' ), bp_get_total_friend_count( bp_loggedin_user_id() ) ); ?></a></li>
+								<li id="activity-friends"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() . '/'; ?>" title="<?php esc_attr_e( 'The activity of my friends only.', 'buddypress' ); ?>"><?php printf( __( 'My Friends <span>%s</span>', 'buddypress' ), bp_get_total_friend_count( bp_loggedin_user_id() ) ); ?></a></li>
 
 							<?php endif; ?>
 
@@ -58,7 +58,7 @@ get_header( 'buddypress' ); ?>
 
 							<?php if ( bp_get_total_group_count_for_user( bp_loggedin_user_id() ) ) : ?>
 
-								<li id="activity-groups"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() . '/'; ?>" title="<?php _e( 'The activity of groups I am a member of.', 'buddypress' ); ?>"><?php printf( __( 'My Groups <span>%s</span>', 'buddypress' ), bp_get_total_group_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
+								<li id="activity-groups"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() . '/'; ?>" title="<?php esc_attr_e( 'The activity of groups I am a member of.', 'buddypress' ); ?>"><?php printf( __( 'My Groups <span>%s</span>', 'buddypress' ), bp_get_total_group_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
 
 							<?php endif; ?>
 
@@ -68,7 +68,7 @@ get_header( 'buddypress' ); ?>
 
 						<?php if ( bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ) : ?>
 
-							<li id="activity-favorites"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/'; ?>" title="<?php _e( "The activity I've marked as a favorite.", 'buddypress' ); ?>"><?php printf( __( 'My Favorites <span>%s</span>', 'buddypress' ), bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
+							<li id="activity-favorites"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/'; ?>" title="<?php esc_attr_e( "The activity I've marked as a favorite.", 'buddypress' ); ?>"><?php printf( __( 'My Favorites <span>%s</span>', 'buddypress' ), bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
 
 						<?php endif; ?>
 
@@ -76,7 +76,7 @@ get_header( 'buddypress' ); ?>
 
 							<?php do_action( 'bp_before_activity_type_tab_mentions' ); ?>
 
-							<li id="activity-mentions"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/'; ?>" title="<?php _e( 'Activity that I have been mentioned in.', 'buddypress' ); ?>"><?php _e( 'Mentions', 'buddypress' ); ?><?php if ( bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ) : ?> <strong><span><?php printf( _nx( '%s new', '%s new', bp_get_total_mention_count_for_user( bp_loggedin_user_id() ), 'Number of new activity mentions', 'buddypress' ), bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ); ?></span></strong><?php endif; ?></a></li>
+							<li id="activity-mentions"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/'; ?>" title="<?php esc_attr_e( 'Activity that I have been mentioned in.', 'buddypress' ); ?>"><?php _e( 'Mentions', 'buddypress' ); ?><?php if ( bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ) : ?> <strong><span><?php printf( _nx( '%s new', '%s new', bp_get_total_mention_count_for_user( bp_loggedin_user_id() ), 'Number of new activity mentions', 'buddypress' ), bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ); ?></span></strong><?php endif; ?></a></li>
 
 						<?php endif; ?>
 
@@ -88,7 +88,7 @@ get_header( 'buddypress' ); ?>
 
 			<div class="item-list-tabs no-ajax" id="subnav" role="navigation">
 				<ul>
-					<li class="feed"><a href="<?php bp_sitewide_activity_feed_link(); ?>" title="<?php _e( 'RSS Feed', 'buddypress' ); ?>"><?php _e( 'RSS', 'buddypress' ); ?></a></li>
+					<li class="feed"><a href="<?php bp_sitewide_activity_feed_link(); ?>" title="<?php esc_attr_e( 'RSS Feed', 'buddypress' ); ?>"><?php _e( 'RSS', 'buddypress' ); ?></a></li>
 
 					<?php do_action( 'bp_activity_syndication_options' ); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/activity/post-form.php b/wp-content/plugins/buddypress/bp-themes/bp-default/activity/post-form.php
index 92d085ecead2479d94f5ac9cef350302d0a59bea..fe0e8921ee301b52486a334120b197a13e3ac2c0 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/activity/post-form.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/activity/post-form.php
@@ -27,12 +27,12 @@
 
 	<div id="whats-new-content">
 		<div id="whats-new-textarea">
-			<textarea name="whats-new" id="whats-new" cols="50" rows="10"><?php if ( isset( $_GET['r'] ) ) : ?>@<?php echo esc_attr( $_GET['r'] ); ?> <?php endif; ?></textarea>
+			<textarea name="whats-new" id="whats-new" cols="50" rows="10"><?php if ( isset( $_GET['r'] ) ) : ?>@<?php echo esc_textarea( $_GET['r'] ); ?> <?php endif; ?></textarea>
 		</div>
 
 		<div id="whats-new-options">
 			<div id="whats-new-submit">
-				<input type="submit" name="aw-whats-new-submit" id="aw-whats-new-submit" value="<?php _e( 'Post Update', 'buddypress' ); ?>" />
+				<input type="submit" name="aw-whats-new-submit" id="aw-whats-new-submit" value="<?php esc_attr_e( 'Post Update', 'buddypress' ); ?>" />
 			</div>
 
 			<?php if ( bp_is_active( 'groups' ) && !bp_is_my_profile() && !bp_is_group() ) : ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/archive.php b/wp-content/plugins/buddypress/bp-themes/bp-default/archive.php
index 1fdfe85d3df15c64616628145841c336dbb46fdc..05340c1e2abebf5836f3bd9eab36675c65b4b8ce 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/archive.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/archive.php
@@ -25,7 +25,7 @@
 						</div>
 
 						<div class="post-content">
-							<h2 class="posttitle"><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php _e( 'Permanent Link to', 'buddypress' ); ?> <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
+							<h2 class="posttitle"><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php esc_attr_e( 'Permanent Link to', 'buddypress' ); ?> <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
 
 							<p class="date"><?php printf( __( '%1$s <span>in %2$s</span>', 'buddypress' ), get_the_date(), get_the_category_list( ', ' ) ); ?></p>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/attachment.php b/wp-content/plugins/buddypress/bp-themes/bp-default/attachment.php
index 8f6d501738d4a4ef41a5379031f51c312d49b851..c5d2f566c49aab82059c5f9a8f3f7e771e0041ad 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/attachment.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/attachment.php
@@ -19,7 +19,7 @@
 						</div>
 
 						<div class="post-content">
-							<h2 class="posttitle"><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php _e( 'Permanent Link to', 'buddypress' ); ?> <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
+							<h2 class="posttitle"><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php esc_attr_e( 'Permanent Link to', 'buddypress' ); ?> <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
 
 							<p class="date">
 								<?php the_date(); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/forums/forums-loop.php b/wp-content/plugins/buddypress/bp-themes/bp-default/forums/forums-loop.php
index 51dea2f571a0ea8d9c1e32698559c47ead95eb2e..ff59639c1223c310dc12a73608cec14d47d5d196 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/forums/forums-loop.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/forums/forums-loop.php
@@ -51,7 +51,7 @@
 
 			<tr class="<?php bp_the_topic_css_class(); ?>">
 				<td class="td-title">
-					<a class="topic-title" href="<?php bp_the_topic_permalink(); ?>" title="<?php _e( 'Permanent link to this post', 'buddypress' ); ?>">
+					<a class="topic-title" href="<?php bp_the_topic_permalink(); ?>" title="<?php esc_attr_e( 'Permanent link to this post', 'buddypress' ); ?>">
 
 						<?php bp_the_topic_title(); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/forums/index.php b/wp-content/plugins/buddypress/bp-themes/bp-default/forums/index.php
index cd8d3e01797f5835009a36dba09af3f97836c65d..eb4485e6259c734c5fe1bf3eec5da1735c2546dd 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/forums/index.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/forums/index.php
@@ -130,8 +130,8 @@
 							<?php do_action( 'groups_forum_new_topic_after' ); ?>
 
 							<div class="submit">
-								<input type="submit" name="submit_topic" id="submit" value="<?php _e( 'Post Topic', 'buddypress' ); ?>" />
-								<input type="button" name="submit_topic_cancel" id="submit_topic_cancel" value="<?php _e( 'Cancel', 'buddypress' ); ?>" />
+								<input type="submit" name="submit_topic" id="submit" value="<?php esc_attr_e( 'Post Topic', 'buddypress' ); ?>" />
+								<input type="button" name="submit_topic_cancel" id="submit_topic_cancel" value="<?php esc_attr_e( 'Cancel', 'buddypress' ); ?>" />
 							</div>
 
 							<?php wp_nonce_field( 'bp_forums_new_topic' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/create.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/create.php
index d2a42246f6b0cbf55edf54277ac0d1b6a36e01a7..7b5489dc83075920ee1280798c2096335230324b 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/create.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/create.php
@@ -150,7 +150,7 @@ get_header( 'buddypress' ); ?>
 
 							<p>
 								<input type="file" name="file" id="file" />
-								<input type="submit" name="upload" id="upload" value="<?php _e( 'Upload Image', 'buddypress' ); ?>" />
+								<input type="submit" name="upload" id="upload" value="<?php esc_attr_e( 'Upload Image', 'buddypress' ); ?>" />
 								<input type="hidden" name="action" id="action" value="bp_avatar_upload" />
 							</p>
 
@@ -163,13 +163,13 @@ get_header( 'buddypress' ); ?>
 
 						<h3><?php _e( 'Crop Group Avatar', 'buddypress' ); ?></h3>
 
-						<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php _e( 'Avatar to crop', 'buddypress' ); ?>" />
+						<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php esc_attr_e( 'Avatar to crop', 'buddypress' ); ?>" />
 
 						<div id="avatar-crop-pane">
-							<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php _e( 'Avatar preview', 'buddypress' ); ?>" />
+							<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php esc_attr_e( 'Avatar preview', 'buddypress' ); ?>" />
 						</div>
 
-						<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php _e( 'Crop Image', 'buddypress' ); ?>" />
+						<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php esc_attr_e( 'Crop Image', 'buddypress' ); ?>" />
 
 						<input type="hidden" name="image_src" id="image_src" value="<?php bp_avatar_to_crop_src(); ?>" />
 						<input type="hidden" name="upload" id="upload" />
@@ -265,28 +265,28 @@ get_header( 'buddypress' ); ?>
 						<?php /* Previous Button */ ?>
 						<?php if ( !bp_is_first_group_creation_step() ) : ?>
 
-							<input type="button" value="<?php _e( 'Back to Previous Step', 'buddypress' ); ?>" id="group-creation-previous" name="previous" onclick="location.href='<?php bp_group_creation_previous_link(); ?>'" />
+							<input type="button" value="<?php esc_attr_e( 'Back to Previous Step', 'buddypress' ); ?>" id="group-creation-previous" name="previous" onclick="location.href='<?php bp_group_creation_previous_link(); ?>'" />
 
 						<?php endif; ?>
 
 						<?php /* Next Button */ ?>
 						<?php if ( !bp_is_last_group_creation_step() && !bp_is_first_group_creation_step() ) : ?>
 
-							<input type="submit" value="<?php _e( 'Next Step', 'buddypress' ); ?>" id="group-creation-next" name="save" />
+							<input type="submit" value="<?php esc_attr_e( 'Next Step', 'buddypress' ); ?>" id="group-creation-next" name="save" />
 
 						<?php endif;?>
 
 						<?php /* Create Button */ ?>
 						<?php if ( bp_is_first_group_creation_step() ) : ?>
 
-							<input type="submit" value="<?php _e( 'Create Group and Continue', 'buddypress' ); ?>" id="group-creation-create" name="save" />
+							<input type="submit" value="<?php esc_attr_e( 'Create Group and Continue', 'buddypress' ); ?>" id="group-creation-create" name="save" />
 
 						<?php endif; ?>
 
 						<?php /* Finish Button */ ?>
 						<?php if ( bp_is_last_group_creation_step() ) : ?>
 
-							<input type="submit" value="<?php _e( 'Finish', 'buddypress' ); ?>" id="group-creation-finish" name="save" />
+							<input type="submit" value="<?php esc_attr_e( 'Finish', 'buddypress' ); ?>" id="group-creation-finish" name="save" />
 
 						<?php endif; ?>
 					</div>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/groups-loop.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/groups-loop.php
index 7059eb98629ff9111dd6f8d46e0535e3c279e9d2..5931e8265a8d8562586bb2e22ce194f2ef05946d 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/groups-loop.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/groups-loop.php
@@ -37,7 +37,7 @@
 
 	<?php while ( bp_groups() ) : bp_the_group(); ?>
 
-		<li>
+		<li <?php bp_group_class(); ?>>
 			<div class="item-avatar">
 				<a href="<?php bp_group_permalink(); ?>"><?php bp_group_avatar( 'type=thumb&width=50&height=50' ); ?></a>
 			</div>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/activity.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/activity.php
index 5dd535ce52a06963a4ea5b4dcec35c36dff75a38..e89d5e1fb56e742eb35e1c5ab16a09d4d1359036 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/activity.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/activity.php
@@ -1,6 +1,6 @@
 <div class="item-list-tabs no-ajax" id="subnav" role="navigation">
 	<ul>
-		<li class="feed"><a href="<?php bp_group_activity_feed_link(); ?>" title="<?php _e( 'RSS Feed', 'buddypress' ); ?>"><?php _e( 'RSS', 'buddypress' ); ?></a></li>
+		<li class="feed"><a href="<?php bp_group_activity_feed_link(); ?>" title="<?php esc_attr_e( 'RSS Feed', 'buddypress' ); ?>"><?php _e( 'RSS', 'buddypress' ); ?></a></li>
 
 		<?php do_action( 'bp_group_activity_syndication_options' ); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/admin.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/admin.php
index 8a6d42dfb74e561cf7e0e39b5e83a4df779b3fc6..5c728ae45e18b34c3e53fe735fdd7795670b0fe3 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/admin.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/admin.php
@@ -29,7 +29,7 @@
 
 	<?php do_action( 'bp_after_group_details_admin' ); ?>
 
-	<p><input type="submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" id="save" name="save" /></p>
+	<p><input type="submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="save" name="save" /></p>
 	<?php wp_nonce_field( 'groups_edit_group_details' ); ?>
 
 <?php endif; ?>
@@ -114,7 +114,7 @@
 
 	<?php do_action( 'bp_after_group_settings_admin' ); ?>
 
-	<p><input type="submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" id="save" name="save" /></p>
+	<p><input type="submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="save" name="save" /></p>
 	<?php wp_nonce_field( 'groups_edit_group_settings' ); ?>
 
 <?php endif; ?>
@@ -128,7 +128,7 @@
 
 			<p>
 				<input type="file" name="file" id="file" />
-				<input type="submit" name="upload" id="upload" value="<?php _e( 'Upload Image', 'buddypress' ); ?>" />
+				<input type="submit" name="upload" id="upload" value="<?php esc_attr_e( 'Upload Image', 'buddypress' ); ?>" />
 				<input type="hidden" name="action" id="action" value="bp_avatar_upload" />
 			</p>
 
@@ -148,13 +148,13 @@
 
 		<h3><?php _e( 'Crop Avatar', 'buddypress' ); ?></h3>
 
-		<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php _e( 'Avatar to crop', 'buddypress' ); ?>" />
+		<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php esc_attr_e( 'Avatar to crop', 'buddypress' ); ?>" />
 
 		<div id="avatar-crop-pane">
-			<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php _e( 'Avatar preview', 'buddypress' ); ?>" />
+			<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php esc_attr_e( 'Avatar preview', 'buddypress' ); ?>" />
 		</div>
 
-		<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php _e( 'Crop Image', 'buddypress' ); ?>" />
+		<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php esc_attr_e( 'Crop Image', 'buddypress' ); ?>" />
 
 		<input type="hidden" name="image_src" id="image_src" value="<?php bp_avatar_to_crop_src(); ?>" />
 		<input type="hidden" id="x" name="x" />
@@ -213,7 +213,7 @@
 						<h5>
 							<a href="<?php bp_member_permalink(); ?>"> <?php bp_member_name(); ?></a>
 							<span class="small">
-								<a href="<?php bp_group_member_promote_admin_link( array( 'user_id' => bp_get_member_user_id() ) ); ?>" class="button confirm mod-promote-to-admin" title="<?php _e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_promote_admin_link( array( 'user_id' => bp_get_member_user_id() ) ); ?>" class="button confirm mod-promote-to-admin" title="<?php esc_attr_e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
 								<a class="button confirm mod-demote-to-member" href="<?php bp_group_member_demote_link( bp_get_member_user_id() ); ?>"><?php _e( 'Demote to Member', 'buddypress' ); ?></a>
 							</span>
 						</h5>
@@ -263,17 +263,17 @@
 
 							<?php if ( bp_get_group_member_is_banned() ) : ?>
 
-								<a href="<?php bp_group_member_unban_link(); ?>" class="button confirm member-unban" title="<?php _e( 'Unban this member', 'buddypress' ); ?>"><?php _e( 'Remove Ban', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_unban_link(); ?>" class="button confirm member-unban" title="<?php esc_attr_e( 'Unban this member', 'buddypress' ); ?>"><?php _e( 'Remove Ban', 'buddypress' ); ?></a>
 
 							<?php else : ?>
 
-								<a href="<?php bp_group_member_ban_link(); ?>" class="button confirm member-ban" title="<?php _e( 'Kick and ban this member', 'buddypress' ); ?>"><?php _e( 'Kick &amp; Ban', 'buddypress' ); ?></a>
-								<a href="<?php bp_group_member_promote_mod_link(); ?>" class="button confirm member-promote-to-mod" title="<?php _e( 'Promote to Mod', 'buddypress' ); ?>"><?php _e( 'Promote to Mod', 'buddypress' ); ?></a>
-								<a href="<?php bp_group_member_promote_admin_link(); ?>" class="button confirm member-promote-to-admin" title="<?php _e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_ban_link(); ?>" class="button confirm member-ban" title="<?php esc_attr_e( 'Kick and ban this member', 'buddypress' ); ?>"><?php _e( 'Kick &amp; Ban', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_promote_mod_link(); ?>" class="button confirm member-promote-to-mod" title="<?php esc_attr_e( 'Promote to Mod', 'buddypress' ); ?>"><?php _e( 'Promote to Mod', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_promote_admin_link(); ?>" class="button confirm member-promote-to-admin" title="<?php esc_attr_e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
 
 							<?php endif; ?>
 
-								<a href="<?php bp_group_member_remove_link(); ?>" class="button confirm" title="<?php _e( 'Remove this member', 'buddypress' ); ?>"><?php _e( 'Remove from group', 'buddypress' ); ?></a>
+								<a href="<?php bp_group_member_remove_link(); ?>" class="button confirm" title="<?php esc_attr_e( 'Remove this member', 'buddypress' ); ?>"><?php _e( 'Remove from group', 'buddypress' ); ?></a>
 
 								<?php do_action( 'bp_group_manage_members_admin_item' ); ?>
 
@@ -357,7 +357,7 @@
 	<?php do_action( 'bp_after_group_delete_admin' ); ?>
 
 	<div class="submit">
-		<input type="submit" disabled="disabled" value="<?php _e( 'Delete Group', 'buddypress' ); ?>" id="delete-group-button" name="delete-group-button" />
+		<input type="submit" disabled="disabled" value="<?php esc_attr_e( 'Delete Group', 'buddypress' ); ?>" id="delete-group-button" name="delete-group-button" />
 	</div>
 
 	<?php wp_nonce_field( 'groups_delete_group' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum.php
index 91b61d250a273b5da59a0afe365cfcd868af58d6..9a4af52c5e16fac18fa25a717754068e7b736515 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum.php
@@ -84,7 +84,7 @@ else : ?>
 				<?php do_action( 'bp_after_group_forum_post_new' ); ?>
 
 				<div class="submit">
-					<input type="submit" name="submit_topic" id="submit" value="<?php _e( 'Post Topic', 'buddypress' ); ?>" />
+					<input type="submit" name="submit_topic" id="submit" value="<?php esc_attr_e( 'Post Topic', 'buddypress' ); ?>" />
 				</div>
 
 				<?php wp_nonce_field( 'bp_forums_new_topic' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum/edit.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum/edit.php
index 57cbc377a3c11d2dd146a87b39cad81d087c278d..23c1f60be661a7293d2a4fbf4a81bdd607e76fef 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum/edit.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum/edit.php
@@ -55,7 +55,7 @@
 
 				<?php do_action( 'bp_group_after_edit_forum_topic' ); ?>
 
-				<p class="submit"><input type="submit" name="save_changes" id="save_changes" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" /></p>
+				<p class="submit"><input type="submit" name="save_changes" id="save_changes" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" /></p>
 
 				<?php wp_nonce_field( 'bp_forums_edit_topic' ); ?>
 
@@ -71,7 +71,7 @@
 
 				<?php do_action( 'bp_group_after_edit_forum_post' ); ?>
 
-				<p class="submit"><input type="submit" name="save_changes" id="save_changes" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" /></p>
+				<p class="submit"><input type="submit" name="save_changes" id="save_changes" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" /></p>
 
 				<?php wp_nonce_field( 'bp_forums_edit_post' ); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum/topic.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum/topic.php
index fff78e139dd6e68b7a20a86a40954895d5a4376e..a70cdabc30aa1e0df3383af1b1ad25fae36e4412 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum/topic.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/forum/topic.php
@@ -92,7 +92,7 @@
 
 						<?php do_action( 'bp_group_forum_post_meta' ); ?>
 
-						<a href="#post-<?php bp_the_topic_post_id(); ?>" title="<?php _e( 'Permanent link to this post', 'buddypress' ); ?>">#</a>
+						<a href="#post-<?php bp_the_topic_post_id(); ?>" title="<?php esc_attr_e( 'Permanent link to this post', 'buddypress' ); ?>">#</a>
 					</div>
 				</li>
 
@@ -141,7 +141,7 @@
 					<textarea name="reply_text" id="reply_text"></textarea>
 
 					<div class="submit">
-						<input type="submit" name="submit_reply" id="submit" value="<?php _e( 'Post Reply', 'buddypress' ); ?>" />
+						<input type="submit" name="submit_reply" id="submit" value="<?php esc_attr_e( 'Post Reply', 'buddypress' ); ?>" />
 					</div>
 
 					<?php do_action( 'groups_forum_new_reply_after' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/request-membership.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/request-membership.php
index 66e0dc9559c7b2f41866a0b3d1db690db17356ad..cace677b8521a864f562c2acda01a94392b7055e 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/request-membership.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/request-membership.php
@@ -9,7 +9,7 @@
 
 		<?php do_action( 'bp_group_request_membership_content' ); ?>
 
-		<p><input type="submit" name="group-request-send" id="group-request-send" value="<?php _e( 'Send Request', 'buddypress' ); ?>" />
+		<p><input type="submit" name="group-request-send" id="group-request-send" value="<?php esc_attr_e( 'Send Request', 'buddypress' ); ?>" />
 
 		<?php wp_nonce_field( 'groups_request_membership' ); ?>
 	</form><!-- #request-membership-form -->
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/send-invites.php b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/send-invites.php
index 498d25494c1e9e7f1e079b7083f06300eec906de..559de6503b9466e93f90076e952ac7cf626a355c 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/send-invites.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/send-invites.php
@@ -57,7 +57,7 @@
 		<div class="clear"></div>
 
 		<div class="submit">
-			<input type="submit" name="submit" id="submit" value="<?php _e( 'Send Invites', 'buddypress' ); ?>" />
+			<input type="submit" name="submit" id="submit" value="<?php esc_attr_e( 'Send Invites', 'buddypress' ); ?>" />
 		</div>
 
 		<?php wp_nonce_field( 'groups_send_invites', '_wpnonce_send_invites'); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/header.php b/wp-content/plugins/buddypress/bp-themes/bp-default/header.php
index b78eb87f578671e0330a1fd4664148c2771eeaa6..aa73e8d46446f764d1a4cf5f951b1e4b9179bd2e 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/header.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/header.php
@@ -19,7 +19,7 @@
 		<div id="header">
 			<div id="search-bar" role="search">
 				<div class="padder">
-					<h1 id="logo" role="banner"><a href="<?php echo home_url(); ?>" title="<?php _ex( 'Home', 'Home page banner link title', 'buddypress' ); ?>"><?php bp_site_name(); ?></a></h1>
+					<h1 id="logo" role="banner"><a href="<?php echo home_url(); ?>" title="<?php echo esc_attr_x( 'Home', 'Home page banner link title', 'buddypress' ); ?>"><?php bp_site_name(); ?></a></h1>
 
 						<form action="<?php echo bp_search_form_action(); ?>" method="post" id="search-form">
 							<label for="search-terms" class="accessibly-hidden"><?php _e( 'Search for:', 'buddypress' ); ?></label>
@@ -27,7 +27,7 @@
 
 							<?php echo bp_search_form_type_select(); ?>
 
-							<input type="submit" name="search-submit" id="search-submit" value="<?php _e( 'Search', 'buddypress' ); ?>" />
+							<input type="submit" name="search-submit" id="search-submit" value="<?php esc_attr_e( 'Search', 'buddypress' ); ?>" />
 
 							<?php wp_nonce_field( 'bp_search_form' ); ?>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/index.php b/wp-content/plugins/buddypress/bp-themes/bp-default/index.php
index 33c8d0f2da3d45fb5d8d10f4bca613e6b440ff49..092913ed1da22c3b4e3ad6ae781626b6aa27ac61 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/index.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/index.php
@@ -29,7 +29,7 @@
 						</div>
 
 						<div class="post-content">
-							<h2 class="posttitle"><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php _e( 'Permanent Link to', 'buddypress' ); ?> <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
+							<h2 class="posttitle"><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php esc_attr_e( 'Permanent Link to', 'buddypress' ); ?> <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
 
 							<p class="date"><?php printf( __( '%1$s <span>in %2$s</span>', 'buddypress' ), get_the_date(), get_the_category_list( ', ' ) ); ?></p>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/friends.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/friends.php
index 70a3a33ef92c84dd75c88991762600fc15681949..f38f2032b1db6b5a641ee61e3625a4ce246b057e 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/friends.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/friends.php
@@ -23,7 +23,7 @@
 					<option value="newest"><?php _e( 'Newest Registered', 'buddypress' ); ?></option>
 					<option value="alphabetical"><?php _e( 'Alphabetical', 'buddypress' ); ?></option>
 
-					<?php do_action( 'bp_member_blog_order_options' ); ?>
+					<?php do_action( 'bp_member_friends_order_options' ); ?>
 
 				</select>
 			</li>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/groups/invites.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/groups/invites.php
index 4d2047fe77c4a9bdfaf69146bcd3606a482be0e1..dbd0a2ec76ad3ba45e5df1c19f91a50e77d4cffb 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/groups/invites.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/groups/invites.php
@@ -11,7 +11,7 @@
 					<a href="<?php bp_group_permalink(); ?>"><?php bp_group_avatar( 'type=thumb&width=50&height=50' ); ?></a>
 				</div>
 
-				<h4><a href="<?php bp_group_permalink(); ?>"><?php bp_group_name(); ?></a><span class="small"> - <?php printf( __( '%s members', 'buddypress' ), bp_group_total_members( false ) ); ?></span></h4>
+				<h4><a href="<?php bp_group_permalink(); ?>"><?php bp_group_name(); ?></a><span class="small"> - <?php printf( _n( '1 member', '%d members', bp_get_group_total_members( false ), 'buddypress' )  ); ?></span></h4>
 
 				<p class="desc">
 					<?php bp_group_description_excerpt(); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/home.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/home.php
index 39d70fbf34ec31d37444fd003038c542051f8153..0c48e276017ab34c14e54ecfce9d5aa41d8b133e 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/home.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/home.php
@@ -60,6 +60,9 @@ get_header( 'buddypress' ); ?>
 				elseif ( bp_is_user_settings() ) :
 					locate_template( array( 'members/single/settings.php'  ), true );
 
+				elseif ( bp_is_user_notifications() ) :
+					locate_template( array( 'members/single/notifications.php' ), true );
+
 				// If nothing sticks, load a generic template
 				else :
 					locate_template( array( 'members/single/plugins.php'   ), true );
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/member-header.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/member-header.php
index cfdc4a0cfb0c3b88c7e1fe193480f55fa2bbb18c..b7086ba1d4d298354b321feb66118701aae106e5 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/member-header.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/member-header.php
@@ -26,7 +26,7 @@
 	</h2>
 
 	<?php if ( bp_is_active( 'activity' ) && bp_activity_do_mentions() ) : ?>
-		<span class="user-nicename">@<?php bp_displayed_user_username(); ?></span>
+		<span class="user-nicename">@<?php bp_displayed_user_mentionname(); ?></span>
 	<?php endif; ?>
 
 	<span class="activity"><?php bp_last_activity( bp_displayed_user_id() ); ?></span>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/compose.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/compose.php
index 9df799c1c13d471fbb6113c1aee91b3e0282a9f5..54ed3af553c74bfdc2629beb2450848403e98c08 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/compose.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/compose.php
@@ -25,7 +25,7 @@
 	<?php do_action( 'bp_after_messages_compose_content' ); ?>
 
 	<div class="submit">
-		<input type="submit" value="<?php _e( "Send Message", 'buddypress' ); ?>" name="send" id="send" />
+		<input type="submit" value="<?php esc_attr_e( "Send Message", 'buddypress' ); ?>" name="send" id="send" />
 	</div>
 
 	<?php wp_nonce_field( 'messages_send_message' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/messages-loop.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/messages-loop.php
index 2e721df896ac1f8cca227c8d5d69803c7a873c91..981a8d2397bc99aaec6e24b5d64aa7ed429c5420 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/messages-loop.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/messages-loop.php
@@ -40,7 +40,7 @@
 				<?php endif; ?>
 
 				<td width="50%" class="thread-info">
-					<p><a href="<?php bp_message_thread_view_link(); ?>" title="<?php _e( "View Message", "buddypress" ); ?>"><?php bp_message_thread_subject(); ?></a></p>
+					<p><a href="<?php bp_message_thread_view_link(); ?>" title="<?php esc_attr_e( "View Message", "buddypress" ); ?>"><?php bp_message_thread_subject(); ?></a></p>
 					<p class="thread-excerpt"><?php bp_message_thread_excerpt(); ?></p>
 				</td>
 
@@ -48,7 +48,7 @@
 
 				<td width="13%" class="thread-options">
 					<input type="checkbox" name="message_ids[]" value="<?php bp_message_thread_id(); ?>" />
-					<a class="button confirm" href="<?php bp_message_thread_delete_link(); ?>" title="<?php _e( "Delete Message", "buddypress" ); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a> &nbsp;
+					<a class="button confirm" href="<?php bp_message_thread_delete_link(); ?>" title="<?php esc_attr_e( "Delete Message", "buddypress" ); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a> &nbsp;
 				</td>
 			</tr>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/notices-loop.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/notices-loop.php
index 5733c8b2fc3ff6cdf33e6117456ff8670951dbef..7f7ba2d3d1de3c432bae5300757cfb8bae880de2 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/notices-loop.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/notices-loop.php
@@ -40,7 +40,7 @@
 
 				<td width="10%">
 					<a class="button" href="<?php bp_message_activate_deactivate_link(); ?>" class="confirm"><?php bp_message_activate_deactivate_text(); ?></a>
-					<a class="button" href="<?php bp_message_notice_delete_link(); ?>" class="confirm" title="<?php _e( "Delete Message", "buddypress" ); ?>">x</a>
+					<a class="button" href="<?php bp_message_notice_delete_link(); ?>" class="confirm" title="<?php esc_attr_e( "Delete Message", "buddypress" ); ?>">x</a>
 				</td>
 			</tr>
 		<?php endwhile; ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/single.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/single.php
index ca07bab163ac96ce4cc990681e05fd2aad296bd8..11c31b125cb7e072e8b9971cb1ec23da2cfa63a3 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/single.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/messages/single.php
@@ -21,7 +21,7 @@
 
 			</span>
 
-			<a class="button confirm" href="<?php bp_the_thread_delete_link(); ?>" title="<?php _e( "Delete Message", "buddypress" ); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a> &nbsp;
+			<a class="button confirm" href="<?php bp_the_thread_delete_link(); ?>" title="<?php esc_attr_e( "Delete Message", "buddypress" ); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a> &nbsp;
 		</p>
 
 		<?php do_action( 'bp_before_message_thread_list' ); ?>
@@ -88,7 +88,7 @@
 					<?php do_action( 'bp_after_message_reply_box' ); ?>
 
 					<div class="submit">
-						<input type="submit" name="send" value="<?php _e( 'Send Reply', 'buddypress' ); ?>" id="send_reply_button"/>
+						<input type="submit" name="send" value="<?php esc_attr_e( 'Send Reply', 'buddypress' ); ?>" id="send_reply_button"/>
 					</div>
 
 					<input type="hidden" id="thread_id" name="thread_id" value="<?php bp_the_thread_id(); ?>" />
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications.php
new file mode 100644
index 0000000000000000000000000000000000000000..c91d118c3901d6af3d9250bd55defb249d894802
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * BuddyPress - Users Notifications
+ *
+ * @package BuddyPress
+ * @subpackage bp-legacy
+ */
+
+?>
+
+<div class="item-list-tabs no-ajax" id="subnav" role="navigation">
+	<ul>
+		<?php bp_get_options_nav(); ?>
+
+		<li id="members-order-select" class="last filter">
+			<?php bp_notifications_sort_order_form(); ?>
+		</li>
+	</ul>
+</div>
+
+<?php
+switch ( bp_current_action() ) :
+
+	// Unread
+	case 'unread' :
+		bp_get_template_part( 'members/single/notifications/unread' );
+		break;
+
+	// Read
+	case 'read' :
+		bp_get_template_part( 'members/single/notifications/read' );
+		break;
+
+	// Any other
+	default :
+		bp_get_template_part( 'members/single/plugins' );
+		break;
+endswitch;
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/feedback-no-notifications.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/feedback-no-notifications.php
new file mode 100644
index 0000000000000000000000000000000000000000..014947bdfb56c6eb43a39240b3f00dff914ccd88
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/feedback-no-notifications.php
@@ -0,0 +1,29 @@
+<div id="message" class="info">
+
+	<?php if ( bp_is_current_action( 'unread' ) ) : ?>
+
+		<?php if ( bp_is_my_profile() ) : ?>
+
+			<p><?php _e( 'You have no unread notifications.', 'buddypress' ); ?></p>
+
+		<?php else : ?>
+
+			<p><?php _e( 'This member has no unread notifications.', 'buddypress' ); ?></p>
+
+		<?php endif; ?>
+			
+	<?php else : ?>
+			
+		<?php if ( bp_is_my_profile() ) : ?>
+
+			<p><?php _e( 'You have no notifications.', 'buddypress' ); ?></p>
+
+		<?php else : ?>
+
+			<p><?php _e( 'This member has no notifications.', 'buddypress' ); ?></p>
+
+		<?php endif; ?>
+
+	<?php endif; ?>
+
+</div>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/notifications-loop.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/notifications-loop.php
new file mode 100644
index 0000000000000000000000000000000000000000..4e5967016b5e10b149933a86676e99a73975a721
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/notifications-loop.php
@@ -0,0 +1,25 @@
+<table class="notifications">
+	<thead>
+		<tr>
+			<th class="icon"></th>
+			<th class="title"><?php _e( 'Notification', 'buddypress' ); ?></th>
+			<th class="date"><?php _e( 'Date Received', 'buddypress' ); ?></th>
+			<th class="actions"><?php _e( 'Actions',    'buddypress' ); ?></th>
+		</tr>
+	</thead>
+
+	<tbody>
+
+		<?php while ( bp_the_notifications() ) : bp_the_notification(); ?>
+
+			<tr>
+				<td></td>
+				<td><?php bp_the_notification_description();  ?></td>
+				<td><?php bp_the_notification_time_since();   ?></td>
+				<td><?php bp_the_notification_action_links(); ?></td>
+			</tr>
+
+		<?php endwhile; ?>
+
+	</tbody>
+</table>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/read.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/read.php
new file mode 100644
index 0000000000000000000000000000000000000000..85fcab77469a5f91c5110d647ccd63b06ff437de
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/read.php
@@ -0,0 +1,29 @@
+<?php if ( bp_has_notifications() ) : ?>
+
+	<div id="pag-top" class="pagination no-ajax">
+		<div class="pag-count" id="notifications-count-top">
+			<?php bp_notifications_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="notifications-pag-top">
+			<?php bp_notifications_pagination_links(); ?>
+		</div>
+	</div>
+
+	<?php bp_get_template_part( 'members/single/notifications/notifications-loop' ); ?>
+
+	<div id="pag-bottom" class="pagination no-ajax">
+		<div class="pag-count" id="notifications-count-bottom">
+			<?php bp_notifications_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="notifications-pag-bottom">
+			<?php bp_notifications_pagination_links(); ?>
+		</div>
+	</div>
+
+<?php else : ?>
+
+	<?php bp_get_template_part( 'members/single/notifications/feedback-no-notifications' ); ?>
+
+<?php endif;
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/unread.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/unread.php
new file mode 100644
index 0000000000000000000000000000000000000000..85fcab77469a5f91c5110d647ccd63b06ff437de
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/notifications/unread.php
@@ -0,0 +1,29 @@
+<?php if ( bp_has_notifications() ) : ?>
+
+	<div id="pag-top" class="pagination no-ajax">
+		<div class="pag-count" id="notifications-count-top">
+			<?php bp_notifications_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="notifications-pag-top">
+			<?php bp_notifications_pagination_links(); ?>
+		</div>
+	</div>
+
+	<?php bp_get_template_part( 'members/single/notifications/notifications-loop' ); ?>
+
+	<div id="pag-bottom" class="pagination no-ajax">
+		<div class="pag-count" id="notifications-count-bottom">
+			<?php bp_notifications_pagination_count(); ?>
+		</div>
+
+		<div class="pagination-links" id="notifications-pag-bottom">
+			<?php bp_notifications_pagination_links(); ?>
+		</div>
+	</div>
+
+<?php else : ?>
+
+	<?php bp_get_template_part( 'members/single/notifications/feedback-no-notifications' ); ?>
+
+<?php endif;
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/profile/change-avatar.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/profile/change-avatar.php
index e1e4851652638de2d944ccf4296aafaa812bfd59..c03774b0684334013e4c765aa4f68a5f183b0abb 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/profile/change-avatar.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/profile/change-avatar.php
@@ -15,13 +15,13 @@
 
 			<p id="avatar-upload">
 				<input type="file" name="file" id="file" />
-				<input type="submit" name="upload" id="upload" value="<?php _e( 'Upload Image', 'buddypress' ); ?>" />
+				<input type="submit" name="upload" id="upload" value="<?php esc_attr_e( 'Upload Image', 'buddypress' ); ?>" />
 				<input type="hidden" name="action" id="action" value="bp_avatar_upload" />
 			</p>
 
 			<?php if ( bp_get_user_has_avatar() ) : ?>
 				<p><?php _e( "If you'd like to delete your current avatar but not upload a new one, please use the delete avatar button.", 'buddypress' ); ?></p>
-				<p><a class="button edit" href="<?php bp_avatar_delete_link(); ?>" title="<?php _e( 'Delete Avatar', 'buddypress' ); ?>"><?php _e( 'Delete My Avatar', 'buddypress' ); ?></a></p>
+				<p><a class="button edit" href="<?php bp_avatar_delete_link(); ?>" title="<?php esc_attr_e( 'Delete Avatar', 'buddypress' ); ?>"><?php _e( 'Delete My Avatar', 'buddypress' ); ?></a></p>
 			<?php endif; ?>
 
 		<?php endif; ?>
@@ -30,13 +30,13 @@
 
 			<h5><?php _e( 'Crop Your New Avatar', 'buddypress' ); ?></h5>
 
-			<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php _e( 'Avatar to crop', 'buddypress' ); ?>" />
+			<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-to-crop" class="avatar" alt="<?php esc_attr_e( 'Avatar to crop', 'buddypress' ); ?>" />
 
 			<div id="avatar-crop-pane">
-				<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php _e( 'Avatar preview', 'buddypress' ); ?>" />
+				<img src="<?php bp_avatar_to_crop(); ?>" id="avatar-crop-preview" class="avatar" alt="<?php esc_attr_e( 'Avatar preview', 'buddypress' ); ?>" />
 			</div>
 
-			<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php _e( 'Crop Image', 'buddypress' ); ?>" />
+			<input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php esc_attr_e( 'Crop Image', 'buddypress' ); ?>" />
 
 			<input type="hidden" name="image_src" id="image_src" value="<?php bp_avatar_to_crop_src(); ?>" />
 			<input type="hidden" id="x" name="x" />
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/profile/edit.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/profile/edit.php
index c4def0ba7540fe1f4d6fd10e113ab4c50035465b..b7b6cc5b6eda03f806aac4b09f935077303376f0 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/profile/edit.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/profile/edit.php
@@ -145,7 +145,7 @@ if ( bp_has_profile( 'profile_group_id=' . bp_get_current_profile_group_id() ) )
 	<?php do_action( 'bp_after_profile_field_content' ); ?>
 
 	<div class="submit">
-		<input type="submit" name="profile-group-edit-submit" id="profile-group-edit-submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?> " />
+		<input type="submit" name="profile-group-edit-submit" id="profile-group-edit-submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?> " />
 	</div>
 
 	<input type="hidden" name="field_ids" id="field_ids" value="<?php bp_the_profile_group_field_ids(); ?>" />
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings.php
index b38fbc979af0328c17df8d763919dea070c95c9d..147ae17efaa8c5d1e92a217565388d1cdff097a0 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings.php
@@ -30,9 +30,10 @@ elseif ( bp_is_current_action( 'delete-account' ) ) :
 elseif ( bp_is_current_action( 'general' ) ) :
 	locate_template( array( 'members/single/settings/general.php' ), true );
 
+elseif ( bp_is_current_action( 'profile' ) ) :
+	locate_template( array( 'members/single/settings/profile.php' ), true );
+
 else :
 	locate_template( array( 'members/single/plugins.php' ), true );
 
 endif;
-
-?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/capabilities.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/capabilities.php
index 19ba3d094074d130242fcd167ecc5c53a4a808a7..062fab1fbe5df2fa3aab4ce26250bb4b33ecd71d 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/capabilities.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/capabilities.php
@@ -58,7 +58,7 @@ get_header( 'buddypress' ); ?>
 					</label>
 
 					<div class="submit">
-						<input type="submit" value="<?php _e( 'Save', 'buddypress' ); ?>" id="capabilities-submit" name="capabilities-submit" />
+						<input type="submit" value="<?php esc_attr_e( 'Save', 'buddypress' ); ?>" id="capabilities-submit" name="capabilities-submit" />
 					</div>
 
 					<?php do_action( 'bp_members_capabilities_account_after_submit' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/delete-account.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/delete-account.php
index c99a7d3ed8cc72e0d3155e0d5dc89c22b808563a..46f743e2ff454299ec80d1f62357c6dc503dbd0f 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/delete-account.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/delete-account.php
@@ -73,7 +73,7 @@
 					</label>
 
 					<div class="submit">
-						<input type="submit" disabled="disabled" value="<?php _e( 'Delete Account', 'buddypress' ); ?>" id="delete-account-button" name="delete-account-button" />
+						<input type="submit" disabled="disabled" value="<?php esc_attr_e( 'Delete Account', 'buddypress' ); ?>" id="delete-account-button" name="delete-account-button" />
 					</div>
 
 					<?php do_action( 'bp_members_delete_account_after_submit' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/general.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/general.php
index 2b410f0288283148d2b446fe7613fd7bb2deef04..894cf618022e6471626fc9b0c26b910f6a08bf33 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/general.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/general.php
@@ -55,7 +55,7 @@ get_header( 'buddypress' ); ?>
 					<?php if ( !is_super_admin() ) : ?>
 
 						<label for="pwd"><?php _e( 'Current Password <span>(required to update email or change current password)</span>', 'buddypress' ); ?></label>
-						<input type="password" name="pwd" id="pwd" size="16" value="" class="settings-input small" /> &nbsp;<a href="<?php echo wp_lostpassword_url(); ?>" title="<?php _e( 'Password Lost and Found', 'buddypress' ); ?>"><?php _e( 'Lost your password?', 'buddypress' ); ?></a>
+						<input type="password" name="pwd" id="pwd" size="16" value="" class="settings-input small" /> &nbsp;<a href="<?php echo wp_lostpassword_url(); ?>" title="<?php esc_attr_e( 'Password Lost and Found', 'buddypress' ); ?>"><?php _e( 'Lost your password?', 'buddypress' ); ?></a>
 
 					<?php endif; ?>
 
@@ -69,7 +69,7 @@ get_header( 'buddypress' ); ?>
 					<?php do_action( 'bp_core_general_settings_before_submit' ); ?>
 
 					<div class="submit">
-						<input type="submit" name="submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
+						<input type="submit" name="submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
 					</div>
 
 					<?php do_action( 'bp_core_general_settings_after_submit' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/notifications.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/notifications.php
index 8d81b789a776e9b6a82473293f10fb4d8b0b8394..62f487ab743713d8c431f09e29f1242274f9d6fd 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/notifications.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/notifications.php
@@ -51,14 +51,14 @@ get_header( 'buddypress' ); ?>
 				<?php do_action( 'bp_template_content' ); ?>
 
 				<form action="<?php echo bp_displayed_user_domain() . bp_get_settings_slug() . '/notifications'; ?>" method="post" class="standard-form" id="settings-form">
-					<p><?php _e( 'Send a notification by email when:', 'buddypress' ); ?></p>
+					<p><?php _e( 'Send an email notice when:', 'buddypress' ); ?></p>
 
 					<?php do_action( 'bp_notification_settings' ); ?>
 
 					<?php do_action( 'bp_members_notification_settings_before_submit' ); ?>
 
 					<div class="submit">
-						<input type="submit" name="submit" value="<?php _e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
+						<input type="submit" name="submit" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
 					</div>
 
 					<?php do_action( 'bp_members_notification_settings_after_submit' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/profile.php b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/profile.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc0db2aecd446cc150e9e11a17ed035e34113539
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/members/single/settings/profile.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * BuddyPress Member Settings
+ *
+ * @package BuddyPress
+ * @subpackage bp-default
+ */
+
+get_header( 'buddypress' ); ?>
+
+	<div id="content">
+		<div class="padder">
+
+			<?php do_action( 'bp_before_member_settings_template' ); ?>
+
+			<div id="item-header">
+
+				<?php locate_template( array( 'members/single/member-header.php' ), true ); ?>
+
+			</div><!-- #item-header -->
+
+			<div id="item-nav">
+				<div class="item-list-tabs no-ajax" id="object-nav" role="navigation">
+					<ul>
+
+						<?php bp_get_displayed_user_nav(); ?>
+
+						<?php do_action( 'bp_member_options_nav' ); ?>
+
+					</ul>
+				</div>
+			</div><!-- #item-nav -->
+
+			<div id="item-body" role="main">
+
+				<?php do_action( 'bp_before_member_body' ); ?>
+
+				<div class="item-list-tabs no-ajax" id="subnav">
+					<ul>
+
+						<?php bp_get_options_nav(); ?>
+
+						<?php do_action( 'bp_member_plugin_options_nav' ); ?>
+
+					</ul>
+				</div><!-- .item-list-tabs -->
+
+				<h3><?php _e( 'Profile Settings', 'buddypress' ); ?></h3>
+
+				<?php do_action( 'bp_template_content' ); ?>
+
+				<form action="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_settings_slug() . '/profile' ); ?>" method="post" class="standard-form" id="settings-form">
+
+					<?php if ( bp_xprofile_get_settings_fields() ) : ?>
+
+						<?php while ( bp_profile_groups() ) : bp_the_profile_group(); ?>
+
+							<?php if ( bp_profile_fields() ) : ?>
+
+								<table class="profile-settings" id="xprofile-settings-<?php bp_the_profile_group_slug(); ?>">
+									<thead>
+										<tr>
+											<th class="title field-group-name"><?php bp_the_profile_group_name(); ?></th>
+											<th class="title"><?php _e( 'Visibility', 'buddypress' ); ?></th>
+										</tr>
+									</thead>
+
+									<tbody>
+
+										<?php while ( bp_profile_fields() ) : bp_the_profile_field(); ?>
+
+											<tr <?php bp_field_css_class(); ?>>
+												<td class="field-name"><?php bp_the_profile_field_name(); ?></td>
+												<td class="field-visibility"><?php bp_profile_settings_visibility_select(); ?></td>
+											</tr>
+
+										<?php endwhile; ?>
+
+									</tbody>
+								</table>
+
+							<?php endif; ?>
+
+						<?php endwhile; ?>
+
+					<?php endif; ?>
+
+					<?php do_action( 'bp_core_xprofile_settings_before_submit' ); ?>
+
+					<div class="submit">
+						<input id="submit" type="submit" name="xprofile-settings-submit" value="<?php esc_attr_e( 'Save Settings', 'buddypress' ); ?>" class="auto" />
+					</div>
+
+					<?php do_action( 'bp_core_xprofile_settings_after_submit' ); ?>
+
+					<?php wp_nonce_field( 'bp_xprofile_settings' ); ?>
+
+					<input type="hidden" name="field_ids" id="field_ids" value="<?php bp_the_profile_group_field_ids(); ?>" />
+
+				</form>
+
+			</div><!-- #item-body -->
+
+			<?php do_action( 'bp_after_member_settings_template' ); ?>
+
+		</div><!-- .padder -->
+	</div><!-- #content -->
+
+<?php get_sidebar( 'buddypress' ); ?>
+
+<?php get_footer( 'buddypress' ); ?>
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/registration/activate.php b/wp-content/plugins/buddypress/bp-themes/bp-default/registration/activate.php
index d2eddc4a32fe8a86058c61b86524c27255799ead..8d48cefb0ec996833ccd5203e70e2ce0f9c8310c 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/registration/activate.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/registration/activate.php
@@ -35,7 +35,7 @@
 					<input type="text" name="key" id="key" value="" />
 
 					<p class="submit">
-						<input type="submit" name="submit" value="<?php _e( 'Activate', 'buddypress' ); ?>" />
+						<input type="submit" name="submit" value="<?php esc_attr_e( 'Activate', 'buddypress' ); ?>" />
 					</p>
 
 				</form>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/registration/register.php b/wp-content/plugins/buddypress/bp-themes/bp-default/registration/register.php
index f70442e02d860b1587d097c5d8472ac520b1c1c9..399b358b258c931ff13e624f747bb5560ce3de9d 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/registration/register.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/registration/register.php
@@ -50,6 +50,8 @@
 					<?php do_action( 'bp_signup_password_confirm_errors' ); ?>
 					<input type="password" name="signup_password_confirm" id="signup_password_confirm" value="" />
 
+					<?php do_action( 'bp_account_details_fields' ); ?>
+
 				</div><!-- #basic-details-section -->
 
 				<?php do_action( 'bp_after_account_details_fields' ); ?>
@@ -65,7 +67,7 @@
 						<h4><?php _e( 'Profile Details', 'buddypress' ); ?></h4>
 
 						<?php /* Use the profile field loop to render input fields for the 'base' profile field group */ ?>
-						<?php if ( bp_is_active( 'xprofile' ) ) : if ( bp_has_profile( 'profile_group_id=1' ) ) : while ( bp_profile_groups() ) : bp_the_profile_group(); ?>
+						<?php if ( bp_is_active( 'xprofile' ) ) : if ( bp_has_profile( array( 'profile_group_id' => 1, 'fetch_field_data' => false ) ) ) : while ( bp_profile_groups() ) : bp_the_profile_group(); ?>
 
 						<?php while ( bp_profile_fields() ) : bp_the_profile_field(); ?>
 
@@ -189,6 +191,8 @@
 
 						<?php endwhile; endif; endif; ?>
 
+						<?php do_action( 'bp_signup_profile_fields' ); ?>
+
 					</div><!-- #profile-details-section -->
 
 					<?php do_action( 'bp_after_signup_profile_fields' ); ?>
@@ -228,6 +232,8 @@
 							<label><input type="radio" name="signup_blog_privacy" id="signup_blog_privacy_public" value="public"<?php if ( 'public' == bp_get_signup_blog_privacy_value() || !bp_get_signup_blog_privacy_value() ) : ?> checked="checked"<?php endif; ?> /> <?php _e( 'Yes', 'buddypress' ); ?></label>
 							<label><input type="radio" name="signup_blog_privacy" id="signup_blog_privacy_private" value="private"<?php if ( 'private' == bp_get_signup_blog_privacy_value() ) : ?> checked="checked"<?php endif; ?> /> <?php _e( 'No', 'buddypress' ); ?></label>
 
+							<?php do_action( 'bp_blog_details_fields' ); ?>
+
 						</div>
 
 					</div><!-- #blog-details-section -->
@@ -239,7 +245,7 @@
 				<?php do_action( 'bp_before_registration_submit_buttons' ); ?>
 
 				<div class="submit">
-					<input type="submit" name="signup_submit" id="signup_submit" value="<?php _e( 'Complete Sign Up', 'buddypress' ); ?>" />
+					<input type="submit" name="signup_submit" id="signup_submit" value="<?php esc_attr_e( 'Complete Sign Up', 'buddypress' ); ?>" />
 				</div>
 
 				<?php do_action( 'bp_after_registration_submit_buttons' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/rtl.css b/wp-content/plugins/buddypress/bp-themes/bp-default/rtl.css
index f6ca05b9521d07c8f94ea79a12b07106614571a8..77c084202edeb55e15db42a2c28cc82108add7f9 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/rtl.css
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/rtl.css
@@ -2,7 +2,7 @@
  * Theme Name: BuddyPress Default
  * Theme URI: http://buddypress.org/extend/themes/
  * Description: Clean and stylish, BuddyPress Default lets you build a social network straight out of the box. Make it yours with a custom menu, header image, and background. Along with five widgetized areas (one in the sidebar, four in the footer), BP-Default supports featured images (as custom header images on posts and pages) and is furnished with an optional one-column page template that removes the sidebar, and a stylesheet for the admin Visual Editor.
- * Version: 1.8.1
+ * Version: 1.9
  * Author: the BuddyPress team
  * Author URI: http://buddypress.org
  * License: GNU General Public License
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/search.php b/wp-content/plugins/buddypress/bp-themes/bp-default/search.php
index 19bde077a63926148e83ea44b1fbff36264223ef..f306770cf4bdfad0390a12d73b54a5553d5b514c 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/search.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/search.php
@@ -27,7 +27,7 @@
 						</div>
 
 						<div class="post-content">
-							<h2 class="posttitle"><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php _e( 'Permanent Link to', 'buddypress' ); ?> <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
+							<h2 class="posttitle"><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php esc_attr_e( 'Permanent Link to', 'buddypress' ); ?> <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
 
 							<p class="date"><?php printf( __( '%1$s <span>in %2$s</span>', 'buddypress' ), get_the_date(), get_the_category_list( ', ' ) ); ?></p>
 
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/searchform.php b/wp-content/plugins/buddypress/bp-themes/bp-default/searchform.php
index 16aa704ccd7551d6e8d1514cd6c17e1fd3b5305e..0b7dcf01465a1c2861abce90627d4a0bcc275fe0 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/searchform.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/searchform.php
@@ -2,7 +2,7 @@
 
 <form role="search" method="get" id="searchform" action="<?php echo home_url(); ?>/">
 	<input type="text" value="<?php the_search_query(); ?>" name="s" id="s" />
-	<input type="submit" id="searchsubmit" value="<?php _e( 'Search', 'buddypress' ); ?>" />
+	<input type="submit" id="searchsubmit" value="<?php esc_attr_e( 'Search', 'buddypress' ); ?>" />
 
 	<?php do_action( 'bp_blog_search_form' ); ?>
 </form>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/sidebar.php b/wp-content/plugins/buddypress/bp-themes/bp-default/sidebar.php
index f04786811c6e925424197c20fce27a7690ff20e6..5f2c1e5fa076b4511ffc7504b77285b95e5630ec 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/sidebar.php
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/sidebar.php
@@ -49,11 +49,10 @@
 
 			<p class="forgetmenot"><label><input name="rememberme" type="checkbox" id="sidebar-rememberme" value="forever" tabindex="99" /> <?php _e( 'Remember Me', 'buddypress' ); ?></label></p>
 
-			<input type="submit" name="wp-submit" id="sidebar-wp-submit" value="<?php _e( 'Log In', 'buddypress' ); ?>" tabindex="100" />
+			<input type="submit" name="wp-submit" id="sidebar-wp-submit" value="<?php esc_attr_e( 'Log In', 'buddypress' ); ?>" tabindex="100" />
 
 			<?php do_action( 'bp_sidebar_login_form' ); ?>
 
-			<input type="hidden" name="testcookie" value="1" />
 		</form>
 
 		<?php do_action( 'bp_after_sidebar_login_form' ); ?>
diff --git a/wp-content/plugins/buddypress/bp-themes/bp-default/style.css b/wp-content/plugins/buddypress/bp-themes/bp-default/style.css
index f6ca05b9521d07c8f94ea79a12b07106614571a8..edb8ce14e15d4446d2fec71e4230f09c113fe55a 100644
--- a/wp-content/plugins/buddypress/bp-themes/bp-default/style.css
+++ b/wp-content/plugins/buddypress/bp-themes/bp-default/style.css
@@ -1,15 +1,17 @@
 /**
  * Theme Name: BuddyPress Default
  * Theme URI: http://buddypress.org/extend/themes/
- * Description: Clean and stylish, BuddyPress Default lets you build a social network straight out of the box. Make it yours with a custom menu, header image, and background. Along with five widgetized areas (one in the sidebar, four in the footer), BP-Default supports featured images (as custom header images on posts and pages) and is furnished with an optional one-column page template that removes the sidebar, and a stylesheet for the admin Visual Editor.
- * Version: 1.8.1
+ * Description: [NOTE: except for security issues, BuddyPress Default is no longer being actively maintained by the BuddyPress team.] Clean and stylish, BuddyPress Default lets you build a social network straight out of the box. Make it yours with a custom menu, header image, and background. Along with five widgetized areas (one in the sidebar, four in the footer), BP-Default supports featured images (as custom header images on posts and pages) and is furnished with an optional one-column page template that removes the sidebar, and a stylesheet for the admin Visual Editor.
+ * Version: 1.9
  * Author: the BuddyPress team
  * Author URI: http://buddypress.org
  * License: GNU General Public License
  * License URI: license.txt
  * Tags: blue, buddypress, custom-background, custom-header, custom-menu, editor-style, featured-image-header, featured-images, fixed-width, light, right-sidebar, rtl-language-support, sticky-post, threaded-comments, translation-ready, two-columns, white
  *
- *** IMPORTANT - DO NOT COPY THIS THEME **
+ *** IMPORTANT ***
+ *
+ * BuddyPress Default is no longer being actively developed by the BuddyPress team.
  *
  * If you want to make a custom theme based on this theme, DO NOT copy and edit it. By
  * doing this you will make updates and maintainence much harder for yourself.
diff --git a/wp-content/plugins/buddypress/bp-xprofile/admin/css/admin.css b/wp-content/plugins/buddypress/bp-xprofile/admin/css/admin.css
index 46b9c4070ac99eb80973d8bcad96a0ee22a816bc..f5a509829ca0fe914bcd84334f540bedea5bd0aa 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/admin/css/admin.css
+++ b/wp-content/plugins/buddypress/bp-xprofile/admin/css/admin.css
@@ -47,7 +47,6 @@
 			color: #aa8;
 		}
 		ul#field-group-tabs li a.ui-tab {
-			font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif;
 			font-size: 14px;
 			display: block;
 			margin-top: 3px;
@@ -241,8 +240,9 @@ th a {
 	top: -2px;
 }
 
-textarea#description {
+textarea#description,
+textarea#group_description {
 	border: 1px solid #ddd;
-	width: 85%;
+	width: 100%;
 }
 
diff --git a/wp-content/plugins/buddypress/bp-xprofile/admin/css/admin.min.css b/wp-content/plugins/buddypress/bp-xprofile/admin/css/admin.min.css
index 51b680c3bc6d5b29d1a7a6f3076ae3552c31f130..51d81e2546fd49b75a5388ea6d5b9b2ba86e5728 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/admin/css/admin.min.css
+++ b/wp-content/plugins/buddypress/bp-xprofile/admin/css/admin.min.css
@@ -1 +1 @@
-#tabs-bottom{background:#f9f9f9;height:32px;border:1px solid #dfdfdf;border-radius:0 0 3px 3px}#tabs{position:relative}p.nofields{margin-top:20px}ul#field-group-tabs{float:left;padding:0 0 0 15px;margin:0;display:none}ul#field-group-tabs li{float:left;margin-bottom:-1px;background-color:transparent;margin-right:8px}ul#field-group-tabs li.ui-state-hover a{background-color:#fafafa}ul#field-group-tabs li.ui-state-hover a.ui-tab{border-color:#dfdfdf #dfdfdf #f9f9f9 #dfdfdf;color:#d54e21}ul#field-group-tabs li.ui-state-acceptable a.ui-tab{border-color:#5a5 #5a5 #ccc #5a5;color:#8a8;background-color:#efe}ul#field-group-tabs li.ui-state-active.ui-state-acceptable a.ui-tab{background-color:#f9f9f9}ul#field-group-tabs li.drop-candidate a.ui-tab{background-color:#ffc;border-color:#aa5 #aa5 #ccc #aa5;color:#aa8}ul#field-group-tabs li a.ui-tab{font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;font-size:14px;display:block;margin-top:3px;padding:5px 10px 5px;border:1px solid #dfdfdf;border-bottom:0;border-radius:3px 3px 0 0;text-decoration:none;color:#aaa}ul#field-group-tabs li.ui-state-active a.ui-tab{background-color:#f9f9f9;margin-top:-1px;padding:7px 10px 7px;border:1px solid #dfdfdf;border-bottom:1px solid transparent;color:#000}.tab-toolbar{background:#f9f9f9;border-width:1px 1px 0;border-radius:3px 3px 0 0;margin:-20px -21px 20px -21px;clear:left;padding:10px;border:1px solid #dfdfdf}.field-wrapper a.deletion,.tab-toolbar a.deletion{color:#f00;border-bottom:1px solid #f00;font-size:12px;text-decoration:none;padding:0;margin:-2px 0 0 5px}div.tab-toolbar a.button-primary{color:#fff!important}div.tab-wrapper{background-color:#fff;clear:left;padding:20px;border-left:1px solid #ccc;border-right:1px solid #ccc;border-radius:3px 3px 0 0}.tab-wrapper fieldset{position:relative;cursor:default!important;background:inherit}.tab-wrapper fieldset legend{padding-bottom:15px;font-weight:bold}.tab-wrapper .xprofile-field{position:relative}.tab-wrapper fieldset fieldset{position:relative;border:1px solid #ddd;border-radius:3px;margin:10px 0 0 0;cursor:move!important;background:#f9f9f9}.tab-wrapper fieldset fieldset legend{position:absolute!important;top:0;left:0;width:80%;padding:30px}.tab-wrapper fieldset fieldset legend span{position:absolute;top:6px;left:10px;font-weight:bold;width:100%}.field-group fieldset:hover{background-color:#fafafa;border-color:#ccc}fieldset div.field-wrapper{padding:40px 10px 10px}fieldset.radio div div label,fieldset.checkbox div label{margin-right:20px}fieldset.clear-value{margin-left:10px}.field-group div.actions{float:none;border-top:1px solid #ddd;margin:20px 0 0;padding-top:10px}.field-group div.actions a,.field-group div.actions button,.field-group div.actions input{float:none}.field-group fieldset:hover div.actions{display:block}.field-group fieldset.ui-sortable-placeholder{border:1px dashed #999;background-color:#eee;visibility:visible!important}ul.forTab{list-style:none;padding:0;margin:0 0 0 1em}ul.forTab li{margin:0 0 1em 0}ul.forTab li label{display:block}ul.forTab li input{font-size:1.4em}p.success{background:green}p.err{border-top:2px solid red;border-bottom:2px solid red;color:red;padding:5px 0;width:40%}span.desc,span.signup-description{display:block;font-size:11px;color:#555}select.multi-select{width:90%;height:10em!important}ul.multi-checkbox{margin:0 5px 0 0;padding:.5em .9em;height:10em;overflow:auto;list-style:none;border:solid 1px #ccc;width:90%}ul.multi-checkbox li{padding:0;margin:0}div.options-box{margin-left:20px!important;margin-right:10px!important;border-left:4px solid #eaf3fa;padding-left:15px}th a{background:#fff;padding:2px 5px;-moz-border-radius:3px;-khtml-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;top:-2px}textarea#description{border:1px solid #ddd;width:85%}
\ No newline at end of file
+#tabs-bottom{background:#f9f9f9;height:32px;border:1px solid #dfdfdf;border-radius:0 0 3px 3px}#tabs{position:relative}p.nofields{margin-top:20px}ul#field-group-tabs{float:left;padding:0 0 0 15px;margin:0;display:none}ul#field-group-tabs li{float:left;margin-bottom:-1px;background-color:transparent;margin-right:8px}ul#field-group-tabs li.ui-state-hover a{background-color:#fafafa}ul#field-group-tabs li.ui-state-hover a.ui-tab{border-color:#dfdfdf #dfdfdf #f9f9f9 #dfdfdf;color:#d54e21}ul#field-group-tabs li.ui-state-acceptable a.ui-tab{border-color:#5a5 #5a5 #ccc #5a5;color:#8a8;background-color:#efe}ul#field-group-tabs li.ui-state-active.ui-state-acceptable a.ui-tab{background-color:#f9f9f9}ul#field-group-tabs li.drop-candidate a.ui-tab{background-color:#ffc;border-color:#aa5 #aa5 #ccc #aa5;color:#aa8}ul#field-group-tabs li a.ui-tab{font-size:14px;display:block;margin-top:3px;padding:5px 10px 5px;border:1px solid #dfdfdf;border-bottom:0;border-radius:3px 3px 0 0;text-decoration:none;color:#aaa}ul#field-group-tabs li.ui-state-active a.ui-tab{background-color:#f9f9f9;margin-top:-1px;padding:7px 10px 7px;border:1px solid #dfdfdf;border-bottom:1px solid transparent;color:#000}.tab-toolbar{background:#f9f9f9;border-width:1px 1px 0;border-radius:3px 3px 0 0;margin:-20px -21px 20px -21px;clear:left;padding:10px;border:1px solid #dfdfdf}.field-wrapper a.deletion,.tab-toolbar a.deletion{color:red;border-bottom:1px solid red;font-size:12px;text-decoration:none;padding:0;margin:-2px 0 0 5px}div.tab-toolbar a.button-primary{color:#fff !important}div.tab-wrapper{background-color:#fff;clear:left;padding:20px;border-left:1px solid #ccc;border-right:1px solid #ccc;border-radius:3px 3px 0 0}.tab-wrapper fieldset{position:relative;cursor:default !important;background:inherit}.tab-wrapper fieldset legend{padding-bottom:15px;font-weight:bold}.tab-wrapper .xprofile-field{position:relative}.tab-wrapper fieldset fieldset{position:relative;border:1px solid #ddd;border-radius:3px;margin:10px 0 0 0;cursor:move !important;background:#f9f9f9}.tab-wrapper fieldset fieldset legend{position:absolute !important;top:0;left:0;width:80%;padding:30px}.tab-wrapper fieldset fieldset legend span{position:absolute;top:6px;left:10px;font-weight:bold;width:100%}.field-group fieldset:hover{background-color:#fafafa;border-color:#ccc}fieldset div.field-wrapper{padding:40px 10px 10px}fieldset.radio div div label,fieldset.checkbox div label{margin-right:20px}fieldset.clear-value{margin-left:10px}.field-group div.actions{float:none;border-top:1px solid #ddd;margin:20px 0 0;padding-top:10px}.field-group div.actions a,.field-group div.actions button,.field-group div.actions input{float:none}.field-group fieldset:hover div.actions{display:block}.field-group fieldset.ui-sortable-placeholder{border:1px dashed #999;background-color:#eee;visibility:visible !important}ul.forTab{list-style:none;padding:0;margin:0 0 0 1em}ul.forTab li{margin:0 0 1em 0}ul.forTab li label{display:block}ul.forTab li input{font-size:1.4em}p.success{background:green}p.err{border-top:2px solid red;border-bottom:2px solid red;color:red;padding:5px 0;width:40%}span.desc,span.signup-description{display:block;font-size:11px;color:#555}select.multi-select{width:90%;height:10em !important}ul.multi-checkbox{margin:0 5px 0 0;padding:.5em .9em;height:10em;overflow:auto;list-style:none;border:solid 1px #ccc;width:90%}ul.multi-checkbox li{padding:0;margin:0}div.options-box{margin-left:20px !important;margin-right:10px !important;border-left:4px solid #eaf3fa;padding-left:15px}th a{background:#fff;padding:2px 5px;-moz-border-radius:3px;-khtml-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;top:-2px}textarea#description,textarea#group_description{border:1px solid #ddd;width:100%}
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-xprofile/admin/js/admin.js b/wp-content/plugins/buddypress/bp-xprofile/admin/js/admin.js
index ac2184eef1f4ee516b551e89d7340b12c38ce0bf..436bd19cc4a996f9e3d8b73c8a88c503c6dd5a84 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/admin/js/admin.js
+++ b/wp-content/plugins/buddypress/bp-xprofile/admin/js/admin.js
@@ -3,10 +3,10 @@ function add_option(forWhat) {
 	var theId     = document.getElementById(forWhat + '_option_number').value;
 	var newDiv    = document.createElement('p');
 	var newOption = document.createElement('input');
-	var span     = document.createElement( 'span' );
+	var span      = document.createElement( 'span' );
 	var txt       = document.createTextNode( "\u00A0\u039E\u00A0" );
 	var isDefault = document.createElement( 'input' );
-	var span1    = document.createElement( 'span' );
+	var span1     = document.createElement( 'span' );
 	var txt1      = document.createTextNode( " Default Value " );
 
 	newDiv.setAttribute('id', forWhat + '_div' + theId);
@@ -79,7 +79,9 @@ function hide( id ) {
 	if ( !document.getElementById( id ) ) return false;
 
 	document.getElementById( id ).style.display = "none";
-	document.getElementById( id ).value = '';
+	// the field id is [fieldtype]option[iterator] and not [fieldtype]div[iterator]
+	field_id = id.replace( 'div', 'option' ); 
+	document.getElementById( field_id ).value = '';
 }
 
 var fixHelper = function(e, ui) {
@@ -91,7 +93,7 @@ var fixHelper = function(e, ui) {
 
 function enableSortableFieldOptions( forWhat ) {
 	if ( jQuery( '#' + forWhat + ' p.sortable' ).length > 1 ) {
-		jQuery( '.options-box' ).sortable( {
+		jQuery( '.bp-options-box' ).sortable( {
 			items: 'p.sortable',
 			tolerance: 'pointer',
 			axis: 'y',
@@ -103,7 +105,7 @@ function enableSortableFieldOptions( forWhat ) {
 }
 
 function destroySortableFieldOptions() {
-	jQuery( '.options-box' ).sortable( 'destroy' );
+	jQuery( '.bp-options-box' ).sortable( 'destroy' );
 	jQuery( '.sortable span' ).css( 'cursor', 'default' );
 }
 
diff --git a/wp-content/plugins/buddypress/bp-xprofile/admin/js/admin.min.js b/wp-content/plugins/buddypress/bp-xprofile/admin/js/admin.min.js
index 44a0856917cecaf07b8c0e9bf6276d98b995091e..17a825f4984d37a07eda45e01763d30a0bddb315 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/admin/js/admin.min.js
+++ b/wp-content/plugins/buddypress/bp-xprofile/admin/js/admin.min.js
@@ -1 +1 @@
-function add_option(g){var j=document.getElementById(g+"_more");var l=document.getElementById(g+"_option_number").value;var a=document.createElement("p");var h=document.createElement("input");var k=document.createElement("span");var e=document.createTextNode("\u00A0\u039E\u00A0");var b=document.createElement("input");var f=document.createElement("span");var d=document.createTextNode(" Default Value ");a.setAttribute("id",g+"_div"+l);a.setAttribute("class","sortable");h.setAttribute("type","text");h.setAttribute("name",g+"_option["+l+"]");h.setAttribute("id",g+"_option"+l);k.appendChild(e);if(g=="checkbox"||g=="multiselectbox"){b.setAttribute("type","checkbox");b.setAttribute("name","isDefault_"+g+"_option["+l+"]")}else{b.setAttribute("type","radio");b.setAttribute("name","isDefault_"+g+"_option")}b.setAttribute("value",l);f.appendChild(d);var c=document.createElement("a");var i=document.createTextNode("[x]");c.setAttribute("href","javascript:hide('"+g+"_div"+l+"')");c.setAttribute("class","delete");c.appendChild(i);a.appendChild(k);a.appendChild(h);a.appendChild(document.createTextNode(" "));a.appendChild(b);a.appendChild(f);a.appendChild(c);j.appendChild(a);enableSortableFieldOptions(g);document.getElementById(g+"_option"+l).focus();l++;document.getElementById(g+"_option_number").value=l}function show_options(a){document.getElementById("radio").style.display="none";document.getElementById("selectbox").style.display="none";document.getElementById("multiselectbox").style.display="none";document.getElementById("checkbox").style.display="none";if(a=="radio"){document.getElementById("radio").style.display=""}if(a=="selectbox"){document.getElementById("selectbox").style.display=""}if(a=="multiselectbox"){document.getElementById("multiselectbox").style.display=""}if(a=="checkbox"){document.getElementById("checkbox").style.display=""}}function hide(a){if(!document.getElementById(a)){return false}document.getElementById(a).style.display="none";document.getElementById(a).value=""}var fixHelper=function(b,a){a.children().each(function(){jQuery(this).width(jQuery(this).width())});return a};function enableSortableFieldOptions(a){if(jQuery("#"+a+" p.sortable").length>1){jQuery(".options-box").sortable({items:"p.sortable",tolerance:"pointer",axis:"y",handle:"span"});jQuery(".sortable span").css("cursor","move")}}function destroySortableFieldOptions(){jQuery(".options-box").sortable("destroy");jQuery(".sortable span").css("cursor","default")}jQuery(document).ready(function(){jQuery("#bp-xprofile-add-field #title").focus();jQuery("a.ajax-option-delete").on("click",function(){var d=this.id.split("-");d=d[1];jQuery.post(ajaxurl,{action:"xprofile_delete_option",cookie:encodeURIComponent(document.cookie),_wpnonce:jQuery("input#_wpnonce").val(),option_id:d},function(e){})});jQuery('[id^="sort_order_"]').change(function(){if(jQuery(this).val()!="custom"){destroySortableFieldOptions()}else{enableSortableFieldOptions(jQuery("#fieldtype :selected").val())}});jQuery("ul#field-group-tabs").show();jQuery("ul#field-group-tabs").sortable({cursor:"move",axis:"x",opacity:0.6,items:"li",tolerance:"pointer",update:function(){jQuery.post(ajaxurl,{action:"xprofile_reorder_groups",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_groups:jQuery("input#_wpnonce_reorder_groups").val(),group_order:jQuery(this).sortable("serialize")},function(d){})}}).disableSelection();jQuery("fieldset.field-group").sortable({cursor:"move",opacity:0.3,items:"fieldset",tolerance:"pointer",update:function(){jQuery.post(ajaxurl,{action:"xprofile_reorder_fields",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_fields:jQuery("input#_wpnonce_reorder_fields").val(),field_order:jQuery(this).sortable("serialize"),field_group_id:jQuery(this).attr("id")},function(d){})}}).disableSelection().css("cursor","move");enableSortableFieldOptions(jQuery("#fieldtype :selected").val());var b;var a=jQuery("#tabs").tabs();c(a);function c(d){b=jQuery("ul:first li",d).droppable({accept:".connectedSortable fieldset",hoverClass:"ui-state-hover",activeClass:"ui-state-acceptable",touch:"pointer",tolerance:"pointer",drop:function(g,h){var e=jQuery(this);var f=jQuery(e.find("a").attr("href")).find(".connectedSortable");jQuery(e).removeClass("drop-candidate");h.draggable.hide("slow",function(){d.tabs("option","active",b.index(e));jQuery(this).appendTo(f).show("slow").animate({opacity:"1"},500);f=jQuery(e.find("a").attr("href")).find(".connectedSortable");jQuery(f).find("p.nofields").hide("slow");jQuery.post(ajaxurl,{action:"xprofile_reorder_fields",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_fields:jQuery("input#_wpnonce_reorder_fields").val(),field_order:jQuery(f).sortable("serialize"),field_group_id:jQuery(f).attr("id")},function(i){})})},over:function(e,f){jQuery(this).addClass("drop-candidate")},out:function(e,f){jQuery(this).removeClass("drop-candidate")}})}});
\ No newline at end of file
+function add_option(g){var j=document.getElementById(g+"_more");var l=document.getElementById(g+"_option_number").value;var a=document.createElement("p");var h=document.createElement("input");var k=document.createElement("span");var e=document.createTextNode("\u00A0\u039E\u00A0");var b=document.createElement("input");var f=document.createElement("span");var d=document.createTextNode(" Default Value ");a.setAttribute("id",g+"_div"+l);a.setAttribute("class","sortable");h.setAttribute("type","text");h.setAttribute("name",g+"_option["+l+"]");h.setAttribute("id",g+"_option"+l);k.appendChild(e);if(g=="checkbox"||g=="multiselectbox"){b.setAttribute("type","checkbox");b.setAttribute("name","isDefault_"+g+"_option["+l+"]")}else{b.setAttribute("type","radio");b.setAttribute("name","isDefault_"+g+"_option")}b.setAttribute("value",l);f.appendChild(d);var c=document.createElement("a");var i=document.createTextNode("[x]");c.setAttribute("href","javascript:hide('"+g+"_div"+l+"')");c.setAttribute("class","delete");c.appendChild(i);a.appendChild(k);a.appendChild(h);a.appendChild(document.createTextNode(" "));a.appendChild(b);a.appendChild(f);a.appendChild(c);j.appendChild(a);enableSortableFieldOptions(g);document.getElementById(g+"_option"+l).focus();l++;document.getElementById(g+"_option_number").value=l}function show_options(a){document.getElementById("radio").style.display="none";document.getElementById("selectbox").style.display="none";document.getElementById("multiselectbox").style.display="none";document.getElementById("checkbox").style.display="none";if(a=="radio"){document.getElementById("radio").style.display=""}if(a=="selectbox"){document.getElementById("selectbox").style.display=""}if(a=="multiselectbox"){document.getElementById("multiselectbox").style.display=""}if(a=="checkbox"){document.getElementById("checkbox").style.display=""}}function hide(a){if(!document.getElementById(a)){return false}document.getElementById(a).style.display="none";field_id=a.replace("div","option");document.getElementById(field_id).value=""}var fixHelper=function(b,a){a.children().each(function(){jQuery(this).width(jQuery(this).width())});return a};function enableSortableFieldOptions(a){if(jQuery("#"+a+" p.sortable").length>1){jQuery(".bp-options-box").sortable({items:"p.sortable",tolerance:"pointer",axis:"y",handle:"span"});jQuery(".sortable span").css("cursor","move")}}function destroySortableFieldOptions(){jQuery(".bp-options-box").sortable("destroy");jQuery(".sortable span").css("cursor","default")}jQuery(document).ready(function(){jQuery("#bp-xprofile-add-field #title").focus();jQuery("a.ajax-option-delete").on("click",function(){var d=this.id.split("-");d=d[1];jQuery.post(ajaxurl,{action:"xprofile_delete_option",cookie:encodeURIComponent(document.cookie),_wpnonce:jQuery("input#_wpnonce").val(),option_id:d},function(e){})});jQuery('[id^="sort_order_"]').change(function(){if(jQuery(this).val()!="custom"){destroySortableFieldOptions()}else{enableSortableFieldOptions(jQuery("#fieldtype :selected").val())}});jQuery("ul#field-group-tabs").show();jQuery("ul#field-group-tabs").sortable({cursor:"move",axis:"x",opacity:0.6,items:"li",tolerance:"pointer",update:function(){jQuery.post(ajaxurl,{action:"xprofile_reorder_groups",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_groups:jQuery("input#_wpnonce_reorder_groups").val(),group_order:jQuery(this).sortable("serialize")},function(d){})}}).disableSelection();jQuery("fieldset.field-group").sortable({cursor:"move",opacity:0.3,items:"fieldset",tolerance:"pointer",update:function(){jQuery.post(ajaxurl,{action:"xprofile_reorder_fields",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_fields:jQuery("input#_wpnonce_reorder_fields").val(),field_order:jQuery(this).sortable("serialize"),field_group_id:jQuery(this).attr("id")},function(d){})}}).disableSelection().css("cursor","move");enableSortableFieldOptions(jQuery("#fieldtype :selected").val());var b;var a=jQuery("#tabs").tabs();c(a);function c(d){b=jQuery("ul:first li",d).droppable({accept:".connectedSortable fieldset",hoverClass:"ui-state-hover",activeClass:"ui-state-acceptable",touch:"pointer",tolerance:"pointer",drop:function(g,h){var e=jQuery(this);var f=jQuery(e.find("a").attr("href")).find(".connectedSortable");jQuery(e).removeClass("drop-candidate");h.draggable.hide("slow",function(){d.tabs("option","active",b.index(e));jQuery(this).appendTo(f).show("slow").animate({opacity:"1"},500);f=jQuery(e.find("a").attr("href")).find(".connectedSortable");jQuery(f).find("p.nofields").hide("slow");jQuery.post(ajaxurl,{action:"xprofile_reorder_fields",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_fields:jQuery("input#_wpnonce_reorder_fields").val(),field_order:jQuery(f).sortable("serialize"),field_group_id:jQuery(f).attr("id")},function(i){})})},over:function(e,f){jQuery(this).addClass("drop-candidate")},out:function(e,f){jQuery(this).removeClass("drop-candidate")}})}});
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-actions.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-actions.php
index 5001fc327a9e7939c57b905caa88d31d2dc027b0..d4fb12076fc28b104eddf3e24021d872418787fb 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-actions.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-actions.php
@@ -43,3 +43,66 @@ function xprofile_action_delete_avatar() {
 	bp_core_redirect( wp_get_referer() );
 }
 add_action( 'bp_actions', 'xprofile_action_delete_avatar' );
+
+/**
+ * Handles the saving of xprofile field visibilities
+ *
+ * @since BuddyPress (1.9)
+ */
+function bp_xprofile_action_settings() {
+
+	// Bail if not a POST action
+	if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) {
+		return;
+	}
+
+	// Bail if no submit action
+	if ( ! isset( $_POST['xprofile-settings-submit'] ) ) {
+		return;
+	}
+
+	// Bail if not in settings
+	if ( ! bp_is_user_settings_profile() ) {
+		return;
+	}
+
+	// 404 if there are any additional action variables attached
+	if ( bp_action_variables() ) {
+		bp_do_404();
+		return;
+	}
+
+	// Nonce check
+	check_admin_referer( 'bp_xprofile_settings' );
+
+	do_action( 'bp_xprofile_settings_before_save' );
+
+	/** Save ******************************************************************/
+
+	// Only save if there are field ID's being posted
+	if ( ! empty( $_POST['field_ids'] ) ) {
+
+		// Get the POST'ed field ID's
+		$posted_field_ids = explode( ',', $_POST['field_ids'] );
+
+		// Save the visibility settings
+		foreach ( $posted_field_ids as $field_id ) {
+
+			$visibility_level = 'public';
+
+			if ( !empty( $_POST['field_' . $field_id . '_visibility'] ) ) {
+				$visibility_level = $_POST['field_' . $field_id . '_visibility'];
+			}
+
+			xprofile_set_field_visibility_level( $field_id, bp_displayed_user_id(), $visibility_level );
+		}
+	}
+
+	/** Other *****************************************************************/
+
+	do_action( 'bp_xprofile_settings_after_save' );
+
+	// Redirect to the root domain
+	bp_core_redirect( bp_displayed_user_domain() . bp_get_settings_slug() . '/profile' );
+}
+add_action( 'bp_actions', 'bp_xprofile_action_settings' );
\ No newline at end of file
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-activity.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-activity.php
index 01ffcc38cbd4ce62295bae37a9dfbaa0d9db4681..8f34b876e750b795a66333094aee01f669fb87f9 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-activity.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-activity.php
@@ -17,14 +17,96 @@ function xprofile_register_activity_actions() {
 	global $bp;
 
 	// Register the activity stream actions for this component
-	bp_activity_set_action( $bp->profile->id, 'new_avatar',      __( 'Member changed profile picture', 'buddypress' ) );
-	bp_activity_set_action( $bp->profile->id, 'new_member',      __( 'New member registered', 'buddypress' ) );
-	bp_activity_set_action( $bp->profile->id, 'updated_profile', __( 'Updated Profile', 'buddypress' ) );
+	bp_activity_set_action(
+		// older avatar activity items use 'profile' for component
+		// see r4273
+		'profile',
+
+		'new_avatar',
+		__( 'Member changed profile picture', 'buddypress' ),
+		'bp_xprofile_format_activity_action_new_avatar'
+	);
+
+	bp_activity_set_action(
+		$bp->profile->id,
+		'new_member',
+		__( 'New member registered', 'buddypress' ),
+		'bp_xprofile_format_activity_action_new_member'
+	);
+
+	bp_activity_set_action(
+		$bp->profile->id,
+		'updated_profile',
+		__( 'Updated Profile', 'buddypress' ),
+		'bp_xprofile_format_activity_action_updated_profile'
+	);
 
 	do_action( 'xprofile_register_activity_actions' );
 }
 add_action( 'bp_register_activity_actions', 'xprofile_register_activity_actions' );
 
+/**
+ * Format 'new_avatar' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param object $activity Activity object.
+ * @return string
+ */
+function bp_xprofile_format_activity_action_new_avatar( $action, $activity ) {
+	$userlink = bp_core_get_userlink( $activity->user_id );
+	$action   = sprintf( __( '%s changed their profile picture', 'buddypress' ), $userlink );
+
+	// Legacy filter - pass $user_id instead of $activity
+	if ( has_filter( 'bp_xprofile_new_avatar_action' ) ) {
+		$action = apply_filters( 'bp_xprofile_new_avatar_action', $action, $activity->user_id );
+	}
+
+	return apply_filters( 'bp_xprofile_format_activity_action_new_avatar', $action, $activity );
+}
+
+/**
+ * Format 'new_member' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param object $activity Activity object.
+ * @return string
+ */
+function bp_xprofile_format_activity_action_new_member( $action, $activity ) {
+	$userlink = bp_core_get_userlink( $activity->user_id );
+	$action   = sprintf( __( '%s became a registered member', 'buddypress' ), $userlink );
+
+	// Legacy filter - pass $user_id instead of $activity
+	if ( has_filter( 'bp_core_activity_registered_member_action' ) ) {
+		$action = apply_filters( 'bp_core_activity_registered_member_action', $action, $activity->user_id );
+	}
+
+	return apply_filters( 'bp_xprofile_format_activity_action_new_member', $action, $activity );
+}
+
+/**
+ * Format 'updated_profile' activity actions.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param string $action Static activity action.
+ * @param object $activity Activity object.
+ * @return string
+ */
+function bp_xprofile_format_activity_action_updated_profile( $action, $activity ) {
+	// Note for translators: The natural phrasing in English, "Joe updated
+	// his profile", requires that we know Joe's gender, which we don't. If
+	// your language doesn't have this restriction, feel free to use a more
+	// natural translation.
+	$profile_link = trailingslashit( bp_core_get_user_domain( $activity->user_id ) . buddypress()->profile->slug );
+	$action	      = sprintf( __( '%s&#8217;s profile was updated', 'buddypress' ), '<a href="' . $profile_link . '">' . bp_core_get_user_displayname( $activity->user_id ) . '</a>' );
+
+	return apply_filters( 'bp_xprofile_format_activity_action_updated_profile', $action, $activity );
+}
+
 /**
  * Records activity for the logged in user within the profile component so that
  * it will show in the users activity stream (if installed)
@@ -126,9 +208,109 @@ function bp_xprofile_new_avatar_activity() {
 
 	bp_activity_add( array(
 		'user_id' => $user_id,
-		'action' => apply_filters( 'bp_xprofile_new_avatar_action', sprintf( __( '%s changed their profile picture', 'buddypress' ), $userlink ), $user_id ),
 		'component' => 'profile',
 		'type' => 'new_avatar'
 	) );
 }
 add_action( 'xprofile_avatar_uploaded', 'bp_xprofile_new_avatar_activity' );
+
+/**
+ * Add an activity item when a user has updated his profile.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $user_id ID of the user who has updated his profile.
+ * @param array $field_ids IDs of the fields submitted.
+ * @param bool $errors True if validation or saving errors occurred, otherwise
+ *        false.
+ * @param array $old_values Pre-save xprofile field values and visibility
+ *        levels.
+ * @param array $new_values Post-save xprofile field values and visibility
+ *        levels.
+ * @return bool True on success, false on failure.
+ */
+function bp_xprofile_updated_profile_activity( $user_id, $field_ids, $errors, $old_values = array(), $new_values = array() ) {
+	// If there were errors, don't post
+	if ( ! empty( $errors ) ) {
+		return false;
+	}
+
+	// Don't post if there have been no changes, or if the changes are
+	// related solely to non-public fields
+	$public_changes = false;
+	foreach ( $new_values as $field_id => $new_value ) {
+		$old_value            = isset( $old_values[ $field_id ] ) ? $old_values[ $field_id ] : '';
+		$old_value_value      = isset( $old_value['value'] ) ? $old_value['value'] : '';
+		$old_value_visibility = isset( $old_value['visibility'] ) ? $old_value['visibility'] : '';
+
+		// Don't register changes to private fields
+		if ( 'public' !== $new_value['visibility'] ) {
+			continue;
+		}
+
+		// Don't register if there have been no changes
+		if ( $new_value === $old_value ) {
+			continue;
+		}
+
+		// Looks like we have public changes - no need to keep checking
+		$public_changes = true;
+		break;
+	}
+
+	if ( ! $public_changes ) {
+		return false;
+	}
+
+	// Throttle to one activity of this type per 2 hours
+	$existing = bp_activity_get( array(
+		'max' => 1,
+		'filter' => array(
+			'user_id' => $user_id,
+			'object'  => buddypress()->profile->id,
+			'action'  => 'updated_profile',
+		),
+	) );
+
+	if ( empty( $existing['activities'] ) ) {
+		$throttle = false;
+	} else {
+		// Default throttle time is 2 hours. Filter to change (in seconds)
+		$throttle_period = apply_filters( 'bp_xprofile_updated_profile_activity_throttle_time', 60 * 60 * 2 );
+		$then = strtotime( $existing['activities'][0]->date_recorded );
+		$now  = strtotime( bp_core_current_time() );
+
+		$throttle = ( $now - $then ) < $throttle_period;
+	}
+
+	if ( $throttle ) {
+		return false;
+	}
+
+	// If we've reached this point, assemble and post the activity item
+	$profile_link = trailingslashit( bp_core_get_user_domain( $user_id ) . buddypress()->profile->slug );
+
+	$retval = xprofile_record_activity( array(
+		'user_id'      => $user_id,
+		'primary_link' => $profile_link,
+		'component'    => buddypress()->profile->id,
+		'type'         => 'updated_profile',
+	) );
+
+	return (bool) $retval;
+}
+add_action( 'xprofile_updated_profile', 'bp_xprofile_updated_profile_activity', 10, 5 );
+
+/**
+ * Add filters for xprofile activity types to Show dropdowns.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function xprofile_activity_filter_options() {
+	?>
+
+	<option value="updated_profile"><?php _e( 'Profile Updates', 'buddypress' ) ?></option>
+
+	<?php
+}
+add_action( 'bp_activity_filter_options', 'xprofile_activity_filter_options' );
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-admin.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-admin.php
index 95151eaecb9668d871ebc1442987547fb92f0d3a..6fc4bc69e392bcf51eaff1bc1b35fa82fc085a9f 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-admin.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-admin.php
@@ -382,87 +382,435 @@ function xprofile_admin_field( $admin_field, $admin_group, $class = '' ) {
 		<legend><span><?php bp_the_profile_field_name(); ?> <?php if( !$field->can_delete ) : ?> <?php _e( '(Primary)', 'buddypress' ); endif; ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(Required)', 'buddypress' ) ?><?php endif; ?></span></legend>
 		<div class="field-wrapper">
 
-			<?php switch ( $field->type ) : case 'textbox' : ?>
+			<?php
+			if ( in_array( $field->type, array_keys( bp_xprofile_get_field_types() ) ) ) {
+				$field_type = bp_xprofile_create_field_type( $field->type );
+				$field_type->admin_field_html();
 
-				<input type="text" name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>" value="" />
+			} else {
+				do_action( 'xprofile_admin_field', $field, 1 );
+			}
+			?>
 
-			<?php break; case 'textarea' : ?>
+			<?php if ( $field->description ) : ?>
 
-				<textarea rows="5" cols="40" name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>"></textarea>
+				<p class="description"><?php echo esc_attr( $field->description ); ?></p>
 
-			<?php break; case 'selectbox' : ?>
+			<?php endif; ?>
 
-				<select name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>">
+			<div class="actions">
+				<a class="button edit" href="users.php?page=bp-profile-setup&amp;group_id=<?php echo esc_attr( $admin_group->id ); ?>&amp;field_id=<?php echo esc_attr( $field->id ); ?>&amp;mode=edit_field"><?php _e( 'Edit', 'buddypress' ); ?></a>
 
-					<?php bp_the_profile_field_options() ?>
+				<?php if ( $field->can_delete ) : ?>
 
-				</select>
+					<a class="confirm submit-delete deletion" href="users.php?page=bp-profile-setup&amp;field_id=<?php echo esc_attr( $field->id ); ?>&amp;mode=delete_field"><?php _e( 'Delete', 'buddypress' ); ?></a>
 
-			<?php break; case 'multiselectbox' : ?>
+				<?php endif; ?>
+			</div>
+		</div>
+	</fieldset>
 
-				<select name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>" multiple="multiple">
+<?php
+}
 
-					<?php bp_the_profile_field_options() ?>
+/**
+ * Print <option> elements containing the xprofile field types.
+ *
+ * @param string $select_field_type The name of the field type that should be selected. Will defaults to "textbox" if NULL is passed.
+ * @since BuddyPress (2.0.0)
+ */
+function bp_xprofile_admin_form_field_types( $select_field_type ) {
+	$categories = array();
 
-				</select>
+	if ( is_null( $select_field_type ) ) {
+		$select_field_type = 'textbox';
+	}
 
-			<?php break; case 'radio' : ?>
+	// Sort each field type into its category
+	foreach ( bp_xprofile_get_field_types() as $field_name => $field_class ) {
+		$field_type_obj = new $field_class;
+		$the_category   = $field_type_obj->category;
 
-				<?php bp_the_profile_field_options() ?>
+		// Fallback to a catch-all if category not set
+		if ( ! $the_category ) {
+			$the_category = _x( 'Other', 'xprofile field type category', 'buddypress' );
+		}
 
-				<?php if ( !bp_get_the_profile_field_is_required() ) : ?>
+		if ( isset( $categories[$the_category] ) ) {
+			$categories[$the_category][] = array( $field_name, $field_type_obj );
+		} else {
+			$categories[$the_category] = array( array( $field_name, $field_type_obj ) );
+		}
+	}
 
-					<a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name() ?>' );"><?php _e( 'Clear', 'buddypress' ) ?></a>
+	// Sort the categories alphabetically. ksort()'s SORT_NATURAL is only in PHP >= 5.4 :((
+	uksort( $categories, 'strnatcmp' );
 
-				<?php endif; ?>
+	// Loop through each category and output form <options>
+	foreach ( $categories as $category => $fields ) {
+		printf( '<optgroup label="%1$s">', esc_attr( $category ) );  // Already i18n'd in each profile type class
+
+		// Sort these fields types alphabetically
+		uasort( $fields, create_function( '$a, $b', 'return strnatcmp( $a[1]->name, $b[1]->name );' ) );
+
+		foreach ( $fields as $field_type_obj ) {
+			$field_name     = $field_type_obj[0];
+			$field_type_obj = $field_type_obj[1];
 
-			<?php break; case 'checkbox' : ?>
+			printf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $field_name ), selected( $select_field_type, $field_name, false ), esc_html( $field_type_obj->name ) );
+		}
 
-				<?php bp_the_profile_field_options(); ?>
+		printf( '</optgroup>' );
+	}
+}
 
-			<?php break; case 'datebox' : ?>
+if ( ! class_exists( 'BP_XProfile_User_Admin' ) ) :
+/**
+ * Load xProfile Profile admin area.
+ *
+ * @package BuddyPress
+ * @subpackage xProfileAdministration
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_User_Admin {
+
+	/**
+	 * Setup xProfile User Admin.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @uses buddypress() to get BuddyPress main instance
+	 */
+	public static function register_xprofile_user_admin() {
+		if( ! is_admin() )
+			return;
+
+		$bp = buddypress();
+
+		if( empty( $bp->profile->admin ) ) {
+			$bp->profile->admin = new self;
+		}
 
-				<select name="<?php bp_the_profile_field_input_name(); ?>_day" id="<?php bp_the_profile_field_input_name(); ?>_day">
+		return $bp->profile->admin;
+	}
 
-					<?php bp_the_profile_field_options( 'type=day' ); ?>
+	/**
+	 * Constructor method.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function __construct() {
+		$this->setup_actions();
+	}
 
-				</select>
+	/**
+	 * Set admin-related actions and filters.
+	 *
+	 * @access private
+	 * @since BuddyPress (2.0.0)
+	 */
+	private function setup_actions() {
 
-				<select name="<?php bp_the_profile_field_input_name(); ?>_month" id="<?php bp_the_profile_field_input_name(); ?>_month">
+		/** Actions ***************************************************/
 
-					<?php bp_the_profile_field_options( 'type=month' ); ?>
+		// Register the metabox in Member's community admin profile
+		add_action( 'bp_members_admin_xprofile_metabox', array( $this, 'register_metaboxes' ), 10, 3 );
 
-				</select>
+		// Saves the profile actions for user ( avatar, profile fields )
+		add_action( 'bp_members_admin_update_user',      array( $this, 'user_admin_load' ),    10, 4 );
 
-				<select name="<?php bp_the_profile_field_input_name(); ?>_year" id="<?php bp_the_profile_field_input_name(); ?>_year">
+	}
 
-					<?php bp_the_profile_field_options( 'type=year' ); ?>
+	/**
+	 * Register the xProfile metabox on Community Profile admin page.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param int $user_id ID of the user being edited.
+	 * @param string $screen_id Screen ID to load the metabox in.
+	 * @param object $stats_metabox Context and priority for the stats metabox.
+	 */
+	public function register_metaboxes( $user_id = 0, $screen_id = '', $stats_metabox = null ) {
+
+		if ( empty( $screen_id ) ) {
+			$screen_id = buddypress()->members->admin->user_page;
+		}
 
-				</select>
+		if ( empty( $stats_metabox ) ) {
+			$stats_metabox = new StdClass();
+		}
 
-			<?php break; default : ?>
+		// Moving the Stats Metabox
+		$stats_metabox->context = 'side';
+		$stats_metabox->priority = 'low';
 
-			<?php do_action( 'xprofile_admin_field', $field, 1 ); ?>
+		// Each Group of fields will have his own metabox
+		if ( false == bp_is_user_spammer( $user_id ) && bp_has_profile( array( 'fetch_fields' => false ) ) ) {
+			while ( bp_profile_groups() ) : bp_the_profile_group();
+				add_meta_box( 'bp_xprofile_user_admin_fields_' . sanitize_key( bp_get_the_profile_group_slug() ), esc_html( bp_get_the_profile_group_name() ), array( &$this, 'user_admin_profile_metaboxes' ), $screen_id, 'normal', 'core', array( 'profile_group_id' => absint( bp_get_the_profile_group_id() ) ) );
+			endwhile;
 
-			<?php endswitch; ?>
+		// if a user has been mark as a spammer, remove BP data
+		} else {
+			add_meta_box( 'bp_xprofile_user_admin_empty_profile', _x( 'User marked as a spammer', 'xprofile user-admin edit screen', 'buddypress' ), array( &$this, 'user_admin_spammer_metabox' ), $screen_id, 'normal', 'core' );
+		}
 
-			<?php if ( $field->description ) : ?>
+		// Avatar Metabox
+		add_meta_box( 'bp_xprofile_user_admin_avatar',  _x( 'Avatar', 'xprofile user-admin edit screen', 'buddypress' ), array( &$this, 'user_admin_avatar_metabox' ), $screen_id, 'side', 'low' );
 
-				<p class="description"><?php echo esc_attr( $field->description ); ?></p>
+	}
 
-			<?php endif; ?>
+	/**
+	 * Save the profile fields in Members community profile page.
+	 *
+	 * Loaded before the page is rendered, this function is processing form
+	 * requests.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function user_admin_load( $doaction = '', $user_id = 0, $request = array(), $redirect_to = '' ) {
 
-			<div class="actions">
-				<a class="button edit" href="users.php?page=bp-profile-setup&amp;group_id=<?php echo esc_attr( $admin_group->id ); ?>&amp;field_id=<?php echo esc_attr( $field->id ); ?>&amp;mode=edit_field"><?php _e( 'Edit', 'buddypress' ); ?></a>
+		// Eventually delete avatar
+		if ( 'delete_avatar' == $doaction ) {
 
-				<?php if ( $field->can_delete ) : ?>
+			check_admin_referer( 'delete_avatar' );
 
-					<a class="confirm submit-delete deletion" href="users.php?page=bp-profile-setup&amp;field_id=<?php echo esc_attr( $field->id ); ?>&amp;mode=delete_field"><?php _e( 'Delete', 'buddypress' ); ?></a>
+			$redirect_to = remove_query_arg( '_wpnonce', $redirect_to );
+
+			if ( bp_core_delete_existing_avatar( array( 'item_id' => $user_id ) ) ) {
+				$redirect_to = add_query_arg( 'updated', 'avatar', $redirect_to );
+			} else {
+				$redirect_to = add_query_arg( 'error', 'avatar', $redirect_to );
+			}
+
+			bp_core_redirect( $redirect_to );
+
+		// Update profile fields
+		} else {
+			// Check to see if any new information has been submitted
+			if ( isset( $_POST['field_ids'] ) ) {
+
+				// Check the nonce
+				check_admin_referer( 'edit-bp-profile_' . $user_id );
+
+				// Check we have field ID's
+				if ( empty( $_POST['field_ids'] ) ) {
+					$redirect_to = add_query_arg( 'error', '1', $redirect_to );
+					bp_core_redirect( $redirect_to );
+				}
+
+				/**
+				 * Unlike front-end edit-fields screens, the wp-admin/profile displays all 
+				 * groups of fields on a single page, so the list of field ids is an array 
+				 * gathering for each group of fields a distinct comma separated list of ids. 
+				 * As a result, before using the wp_parse_id_list() function, we must ensure 
+				 * that these ids are "merged" into a single comma separated list.
+				 */
+				$merge_ids = join( ',', $_POST['field_ids'] );
+
+				// Explode the posted field IDs into an array so we know which fields have been submitted
+				$posted_field_ids = wp_parse_id_list( $merge_ids );
+				$is_required      = array();
+
+				// Loop through the posted fields formatting any datebox values then validate the field
+				foreach ( (array) $posted_field_ids as $field_id ) {
+					if ( ! isset( $_POST['field_' . $field_id] ) ) {
+						if ( ! empty( $_POST['field_' . $field_id . '_day'] ) && ! empty( $_POST['field_' . $field_id . '_month'] ) && ! empty( $_POST['field_' . $field_id . '_year'] ) ) {
+							// Concatenate the values
+							$date_value =   $_POST['field_' . $field_id . '_day'] . ' ' . $_POST['field_' . $field_id . '_month'] . ' ' . $_POST['field_' . $field_id . '_year'];
+
+							// Turn the concatenated value into a timestamp
+							$_POST['field_' . $field_id] = date( 'Y-m-d H:i:s', strtotime( $date_value ) );
+						}
+					}
+
+					$is_required[ $field_id ] = xprofile_check_is_required_field( $field_id );
+					if ( $is_required[ $field_id ] && empty( $_POST['field_' . $field_id] ) ) {
+						$redirect_to = add_query_arg( 'error', '2', $redirect_to );
+						bp_core_redirect( $redirect_to );
+					}
+				}
+
+				// Set the errors var
+				$errors = false;
+
+				// Now we've checked for required fields, let's save the values.
+				foreach ( (array) $posted_field_ids as $field_id ) {
+
+					// Certain types of fields (checkboxes, multiselects) may come through empty. Save them as an empty array so that they don't get overwritten by the default on the next edit.
+					$value = isset( $_POST['field_' . $field_id] ) ? $_POST['field_' . $field_id] : '';
+
+					if ( ! xprofile_set_field_data( $field_id, $user_id, $value, $is_required[ $field_id ] ) ) {
+						$errors = true;
+					} else {
+						do_action( 'xprofile_profile_field_data_updated', $field_id, $value );
+					}
+
+					// Save the visibility level
+					$visibility_level = ! empty( $_POST['field_' . $field_id . '_visibility'] ) ? $_POST['field_' . $field_id . '_visibility'] : 'public';
+					xprofile_set_field_visibility_level( $field_id, $user_id, $visibility_level );
+				}
+
+				do_action( 'xprofile_updated_profile', $user_id, $posted_field_ids, $errors );
+
+				// Set the feedback messages
+				if ( ! empty( $errors ) ) {
+					$redirect_to = add_query_arg( 'error', '3', $redirect_to );
+				} else {
+					$redirect_to = add_query_arg( 'updated', '1', $redirect_to );
+				}
+
+				bp_core_redirect( $redirect_to );
+			}
+		}
+	}
+
+	/**
+	 * Render the xprofile metabox for Community Profile screen.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param WP_User $user The WP_User object for the user being edited.
+	 */
+	public function user_admin_profile_metaboxes( $user = null, $args = array() ) {
+
+		if ( empty( $user->ID ) ) {
+			return;
+		}
+
+		$r = bp_parse_args( $args['args'], array(
+			'profile_group_id' => 0,
+			'user_id'          => $user->ID
+		), 'bp_xprofile_user_admin_profile_loop_args' );
+
+		// We really need these args
+		if ( empty( $r['profile_group_id'] ) || empty( $r['user_id'] ) ) {
+			return;
+		}
+
+		if ( bp_has_profile( $r ) ) :
+			while ( bp_profile_groups() ) : bp_the_profile_group(); ?>
+				<input type="hidden" name="field_ids[]" id="<?php echo esc_attr( 'field_ids_' . bp_get_the_profile_group_slug() ); ?>" value="<?php echo esc_attr( bp_get_the_profile_group_field_ids() ); ?>" />
+
+				<?php if ( bp_get_the_profile_group_description() ) : ?>
+					<p class="description"><?php bp_the_profile_group_description(); ?></p>
+				<?php
+				endif;
+
+				while ( bp_profile_fields() ) : bp_the_profile_field(); ?>
+
+					<div<?php bp_field_css_class( 'bp-profile-field' ); ?>>
+						<?php
+						$field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() );
+						$field_type->edit_field_html( array( 'user_id' => $r['user_id'] ) );
+
+						if ( bp_get_the_profile_field_description() ) : ?>
+							<p class="description"><?php bp_the_profile_field_description(); ?></p>
+						<?php endif;
+
+						do_action( 'bp_custom_profile_edit_fields_pre_visibility' );
+						$can_change_visibility = bp_current_user_can( 'bp_xprofile_change_field_visibility' );
+						?>
+
+						<p class="field-visibility-settings-<?php echo $can_change_visibility ? 'toggle' : 'notoggle'; ?>" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id(); ?>">
+							<?php
+							printf( __( 'This field can be seen by: <span class="%s">%s</span>', 'buddypress' ), esc_attr( 'current-visibility-level' ), bp_get_the_profile_field_visibility_level_label() );
+
+							if ( $can_change_visibility ) : ?>
+								 <a href="#" class="button visibility-toggle-link"><?php _e( 'Change', 'buddypress' ); ?></a>
+							<?php endif; ?>
+						</p>
+
+						<?php if ( $can_change_visibility ) : ?>
+							<div class="field-visibility-settings" id="field-visibility-settings-<?php bp_the_profile_field_id() ?>">
+								<fieldset>
+									<legend><?php _e( 'Who can see this field?', 'buddypress' ); ?></legend>
+									<?php bp_profile_visibility_radio_buttons(); ?>
+								</fieldset>
+								<a class="button field-visibility-settings-close" href="#"><?php _e( 'Close', 'buddypress' ); ?></a>
+							</div>
+						<?php endif;
+
+						do_action( 'bp_custom_profile_edit_fields' ); ?>
+					</div>
+
+				<?php
+				endwhile; // bp_profile_fields()
+
+			endwhile; // bp_profile_groups()
+		endif;
+	}
+
+	/**
+	 * Render the fallback metabox in case a user has been marked as a spammer.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param WP_User $user The WP_User object for the user being edited.
+	 */
+	public function user_admin_spammer_metabox( $user = null ) {
+		?>
+		<p><?php printf( __( '%s has been marked as a spammer. All BuddyPress data associated with the user has been removed', 'buddypress' ), esc_html( bp_core_get_user_displayname( $user->ID ) ) ) ;?></p>
+		<?php
+	}
+
+	/**
+	 * Render the Avatar metabox to moderate inappropriate images.
+	 *
+	 * @access public
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param WP_User $user The WP_User object for the user being edited.
+	 */
+	public function user_admin_avatar_metabox( $user = null ) {
+
+		if ( empty( $user->ID ) ) {
+			return;
+		}
+
+		$args = array(
+			'item_id' => $user->ID,
+			'object'  => 'user',
+			'type'    => 'full',
+			'title'   => $user->display_name
+		);
+
+		?>
+
+		<div class="avatar">
+
+			<?php echo bp_core_fetch_avatar( $args ); ?>
+
+			<?php if ( bp_get_user_has_avatar( $user->ID ) ) :
+
+				$query_args = array(
+					'user_id' => $user->ID,
+					'action'  => 'delete_avatar'
+				);
+
+				if ( ! empty( $_REQUEST['wp_http_referer'] ) )
+					$query_args['wp_http_referer'] = urlencode( wp_unslash( $_REQUEST['wp_http_referer'] ) );
+
+					$community_url = add_query_arg( $query_args, buddypress()->members->admin->edit_profile_url );
+					$delete_link   = wp_nonce_url( $community_url, 'delete_avatar' ); ?>
+
+				<a href="<?php echo esc_url( $delete_link ); ?>" title="<?php esc_attr_e( 'Delete Avatar', 'buddypress' ); ?>" class="bp-xprofile-avatar-user-admin"><?php esc_html_e( 'Delete Avatar', 'buddypress' ); ?></a></li>
+
+			<?php endif; ?>
 
-				<?php endif; ?>
-			</div>
 		</div>
-	</fieldset>
+		<?php
+	}
 
-<?php
 }
+endif; // class_exists check
+
+// Load the xprofile user admin
+add_action( 'bp_init', array( 'BP_XProfile_User_Admin', 'register_xprofile_user_admin' ), 11 );
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-cache.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-cache.php
index eaac569d82c7ac6715c311a14841c0d53880b9a9..0ad410363b3d86f3c1e23f519709875e29c9d35f 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-cache.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-cache.php
@@ -1,31 +1,204 @@
 <?php
 
 /**
- * BuddyPress XProfile Template Tags
+ * BuddyPress XProfile Caching Functions
  *
  * Caching functions handle the clearing of cached objects and pages on specific
  * actions throughout BuddyPress.
  *
  * @package BuddyPress
- * @subpackage XProfileTemplate
  */
 
 // Exit if accessed directly
 if ( !defined( 'ABSPATH' ) ) exit;
 
+/**
+ * Slurp up xprofilemeta for a specified set of profile objects.
+ *
+ * We do not use bp_update_meta_cache() for the xprofile component. This is
+ * because the xprofile component has three separate object types (group,
+ * field, and data) and three corresponding cache groups. Using the technique
+ * in bp_update_meta_cache(), pre-fetching would take three separate database
+ * queries. By grouping them together, we can reduce the required queries to
+ * one.
+ *
+ * This function is called within a bp_has_profile() loop.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $object_ids Multi-dimensional array of object_ids, keyed by
+ *        object type ('group', 'field', 'data')
+ */
+function bp_xprofile_update_meta_cache( $object_ids = array(), $user_id = 0 ) {
+	global $wpdb;
+
+	if ( empty( $object_ids ) ) {
+		return false;
+	}
+
+	// $object_ids is a multi-dimensional array
+	$uncached_object_ids = array(
+		'group' => array(),
+		'field' => array(),
+		'data'   => array(),
+	);
+
+	$cache_groups = array(
+		'group' => 'xprofile_group_meta',
+		'field' => 'xprofile_field_meta',
+		'data'  => 'xprofile_data_meta',
+	);
+
+	$do_query = false;
+	foreach ( $uncached_object_ids as $object_type => $uncached_object_type_ids ) {
+		if ( ! empty( $object_ids[ $object_type ] ) ) {
+			// Sanitize $object_ids passed to the function
+			$object_type_ids = wp_parse_id_list( $object_ids[ $object_type ] );
+
+			// Get non-cached IDs for each object type
+			$uncached_object_ids[ $object_type ] = bp_get_non_cached_ids( $object_type_ids, $cache_groups[ $object_type ] );
+
+			// Set the flag to do the meta query
+			if ( ! empty( $uncached_object_ids[ $object_type ] ) && ! $do_query ) {
+				$do_query = true;
+			}
+		}
+	}
+
+	// If there are uncached items, go ahead with the query
+	if ( $do_query ) {
+		$where = array();
+		foreach ( $uncached_object_ids as $otype => $oids ) {
+			if ( empty( $oids ) ) {
+				continue;
+			}
+
+			$oids_sql = implode( ',', wp_parse_id_list( $oids ) );
+			$where[]  = $wpdb->prepare( "( object_type = %s AND object_id IN ({$oids_sql}) )", $otype );
+		}
+		$where_sql = implode( " OR ", $where );
+	}
+
+
+	$bp = buddypress();
+	$meta_list = $wpdb->get_results( "SELECT object_id, object_type, meta_key, meta_value FROM {$bp->profile->table_name_meta} WHERE {$where_sql}" );
+
+	if ( ! empty( $meta_list ) ) {
+		$object_type_caches = array(
+			'group' => array(),
+			'field' => array(),
+			'data'  => array(),
+		);
+
+		foreach ( $meta_list as $meta ) {
+			$oid    = $meta->object_id;
+			$otype  = $meta->object_type;
+			$okey   = $meta->meta_key;
+			$ovalue = $meta->meta_value;
+
+			// Force subkeys to be array type
+			if ( ! isset( $cache[ $otype ][ $oid ] ) || ! is_array( $cache[ $otype ][ $oid ] ) ) {
+				$cache[ $otype ][ $oid ] = array();
+			}
+
+			if ( ! isset( $cache[ $otype ][ $oid ][ $okey ] ) || ! is_array( $cache[ $otype ][ $oid ][ $okey ] ) ) {
+				$cache[ $otype ][ $oid ][ $okey ] = array();
+			}
+
+			// Add to the cache array
+			$cache[ $otype ][ $oid ][ $okey ][] = maybe_unserialize( $ovalue );
+		}
+
+		foreach ( $cache as $object_type => $object_caches ) {
+			$cache_group = $cache_groups[ $object_type ];
+			foreach ( $object_caches as $object_id => $object_cache ) {
+				wp_cache_set( $object_id, $object_cache, $cache_group );
+			}
+		}
+	}
+
+	return;
+}
+
 function xprofile_clear_profile_groups_object_cache( $group_obj ) {
 	wp_cache_delete( 'xprofile_groups_inc_empty',        'bp' );
 	wp_cache_delete( 'xprofile_group_' . $group_obj->id, 'bp' );
 }
+add_action( 'xprofile_group_after_delete', 'xprofile_clear_profile_groups_object_cache' );
+add_action( 'xprofile_group_after_save',   'xprofile_clear_profile_groups_object_cache' );
 
 function xprofile_clear_profile_data_object_cache( $group_id ) {
 	wp_cache_delete( 'bp_user_fullname_' . bp_loggedin_user_id(), 'bp' );
 }
+add_action( 'xprofile_updated_profile', 'xprofile_clear_profile_data_object_cache'   );
 
-// List actions to clear object caches on
-add_action( 'xprofile_groups_deleted_group', 'xprofile_clear_profile_groups_object_cache' );
-add_action( 'xprofile_groups_saved_group',   'xprofile_clear_profile_groups_object_cache' );
-add_action( 'xprofile_updated_profile',      'xprofile_clear_profile_data_object_cache'   );
+/**
+ * Clear the fullname cache when field 1 is updated.
+ *
+ * xprofile_clear_profile_data_object_cache() will make this redundant in most
+ * cases, except where the field is updated directly with xprofile_set_field_data()
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function xprofile_clear_fullname_cache_on_profile_field_edit( $data ) {
+	if ( 1 == $data->field_id ) {
+		wp_cache_delete( 'bp_user_fullname_' . $data->user_id, 'bp' );
+	}
+}
+add_action( 'xprofile_data_after_save', 'xprofile_clear_fullname_cache_on_profile_field_edit' );
+
+/**
+ * Clear caches when a field object is modified.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param BP_XProfile_Field
+ */
+function xprofile_clear_profile_field_object_cache( $field_obj ) {
+	// Clear default visibility level cache
+	wp_cache_delete( 'xprofile_default_visibility_levels', 'bp' );
+
+	// Modified fields can alter parent group status, in particular when
+	// the group goes from empty to non-empty. Bust its cache, as well as
+	// the global group_inc_empty cache
+	wp_cache_delete( 'xprofile_group_' . $field_obj->group_id, 'bp' );
+	wp_cache_delete( 'xprofile_groups_inc_empty', 'bp' );
+}
+add_action( 'xprofile_fields_saved_field', 'xprofile_clear_profile_field_object_cache' );
+add_action( 'xprofile_fields_deleted_field', 'xprofile_clear_profile_field_object_cache' );
+
+/**
+ * Clear caches when a user's updates a field data object.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param BP_XProfile_ProfileData $data_obj
+ */
+function xprofile_clear_profiledata_object_cache( $data_obj ) {
+	wp_cache_delete( $data_obj->field_id, 'bp_xprofile_data_' . $data_obj->user_id );
+}
+add_action( 'xprofile_data_after_save', 'xprofile_clear_profiledata_object_cache' );
+add_action( 'xprofile_data_after_delete', 'xprofile_clear_profiledata_object_cache' );
+
+/**
+ * Clear fullname_field_id cache when bp-xprofile-fullname-field-name is updated.
+ *
+ * Note for future developers: Dating from an early version of BuddyPress where
+ * the fullname field (field #1) did not have a title that was editable in the
+ * normal Profile Fields admin interface, we have the bp-xprofile-fullname-field-name
+ * option. In many places throughout BuddyPress, the ID of the fullname field
+ * is queried using this setting. However, this is no longer strictly necessary,
+ * because we essentially hardcode (in the xprofile admin save routine, as well
+ * as the xprofile schema definition) that the fullname field will be 1. The
+ * presence of the non-hardcoded versions (and thus this bit of cache
+ * invalidation) is thus for backward compatibility only.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function xprofile_clear_fullname_field_id_cache() {
+	wp_cache_delete( 'fullname_field_id', 'bp_xprofile' );
+}
+add_action( 'update_option_bp-xprofile-fullname-field-name', 'xprofile_clear_fullname_field_id_cache' );
 
 // List actions to clear super cached pages on, if super cache is installed
 add_action( 'xprofile_updated_profile', 'bp_core_clear_cache' );
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-classes.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-classes.php
index 6be33674bf76043c202bbeb7838c029adacb21ff..5351ca4e72a5a708c3addc84e095127af6fcc7b9 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-classes.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-classes.php
@@ -11,25 +11,30 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 class BP_XProfile_Group {
-	var $id = null;
-	var $name;
-	var $description;
-	var $can_delete;
-	var $group_order;
-	var $fields;
-
-	function __construct( $id = null ) {
+	public $id = null;
+	public $name;
+	public $description;
+	public $can_delete;
+	public $group_order;
+	public $fields;
+
+	public function __construct( $id = null ) {
 		if ( !empty( $id ) )
 			$this->populate( $id );
 	}
 
-	function populate( $id ) {
+	public function populate( $id ) {
 		global $wpdb, $bp;
 
-		$sql = $wpdb->prepare( "SELECT * FROM {$bp->profile->table_name_groups} WHERE id = %d", $id );
+		$group = wp_cache_get( 'xprofile_group_' . $this->id, 'bp' );
 
-		if ( !$group = $wpdb->get_row( $sql ) )
+		if ( false === $group ) {
+			$group = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->profile->table_name_groups} WHERE id = %d", $id ) );
+		}
+
+		if ( empty( $group ) ) {
 			return false;
+		}
 
 		$this->id          = $group->id;
 		$this->name        = stripslashes( $group->name );
@@ -38,7 +43,7 @@ class BP_XProfile_Group {
 		$this->group_order = $group->group_order;
 	}
 
-	function save() {
+	public function save() {
 		global $wpdb, $bp;
 
 		$this->name        = apply_filters( 'xprofile_group_name_before_save',        $this->name,        $this->id );
@@ -63,12 +68,14 @@ class BP_XProfile_Group {
 		return $this->id;
 	}
 
-	function delete() {
+	public function delete() {
 		global $wpdb, $bp;
 
 		if ( empty( $this->can_delete ) )
 			return false;
 
+		do_action_ref_array( 'xprofile_group_before_delete', array( &$this ) );
+
 		// Delete field group
 		if ( !$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_groups} WHERE id = %d", $this->id ) ) ) {
 			return false;
@@ -83,6 +90,8 @@ class BP_XProfile_Group {
 				}
 			}
 
+			do_action_ref_array( 'xprofile_group_after_delete', array( &$this ) );
+
 			return true;
 		}
 	}
@@ -108,10 +117,12 @@ class BP_XProfile_Group {
 	 *		'fetch_field_data' - Load each field's data. Requires a user_id
 	 *		'exclude_groups' - Comma-separated list of groups to exclude
 	 *		'exclude_fields' - Comma-separated list of fields to exclude
+	 *		'update_meta_cache' - Whether to pre-fetch xprofilemeta
+	 *		   for all retrieved groups, fields, and data
 	 *
 	 * @return array $groups
 	 */
-	function get( $args = '' ) {
+	public static function get( $args = array() ) {
 		global $wpdb, $bp;
 
 		$defaults = array(
@@ -123,11 +134,20 @@ class BP_XProfile_Group {
 			'fetch_field_data'       => false,
 			'fetch_visibility_level' => false,
 			'exclude_groups'         => false,
-			'exclude_fields'         => false
+			'exclude_fields'         => false,
+			'update_meta_cache'      => true,
 		);
 
 		$r = wp_parse_args( $args, $defaults );
 		extract( $r, EXTR_SKIP );
+
+		// Keep track of object IDs for cache-priming
+		$object_ids = array(
+			'group' => array(),
+			'field' => array(),
+			'data'  => array(),
+		);
+
 		$where_sql = '';
 
 		if ( !empty( $profile_group_id ) )
@@ -135,10 +155,13 @@ class BP_XProfile_Group {
 		elseif ( $exclude_groups )
 			$where_sql = $wpdb->prepare( "WHERE g.id NOT IN ({$exclude_groups})");
 
-		if ( !empty( $hide_empty_groups ) )
-			$groups = $wpdb->get_results( "SELECT DISTINCT g.* FROM {$bp->profile->table_name_groups} g INNER JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id {$where_sql} ORDER BY g.group_order ASC" );
-		else
-			$groups = $wpdb->get_results( "SELECT DISTINCT g.* FROM {$bp->profile->table_name_groups} g {$where_sql} ORDER BY g.group_order ASC" );
+		if ( ! empty( $hide_empty_groups ) ) {
+			$group_ids = $wpdb->get_col( "SELECT DISTINCT g.id FROM {$bp->profile->table_name_groups} g INNER JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id {$where_sql} ORDER BY g.group_order ASC" );
+		} else {
+			$group_ids = $wpdb->get_col( "SELECT DISTINCT g.id FROM {$bp->profile->table_name_groups} g {$where_sql} ORDER BY g.group_order ASC" );
+		}
+
+		$groups = self::get_group_data( $group_ids );
 
 		if ( empty( $fetch_fields ) )
 			return $groups;
@@ -149,6 +172,9 @@ class BP_XProfile_Group {
 			$group_ids[] = $group->id;
 		}
 
+		// Store for meta cache priming
+		$object_ids['group'] = $group_ids;
+
 		$group_ids = implode( ',', (array) $group_ids );
 
 		if ( empty( $group_ids ) )
@@ -171,9 +197,13 @@ class BP_XProfile_Group {
 		// Fetch the fields
 		$fields = $wpdb->get_results( "SELECT id, name, description, type, group_id, is_required FROM {$bp->profile->table_name_fields} WHERE group_id IN ( {$group_ids} ) AND parent_id = 0 {$exclude_fields_sql} ORDER BY field_order" );
 
+		// Store field IDs for meta cache priming
+		$object_ids['field'] = wp_list_pluck( $fields, 'id' );
+
 		if ( empty( $fields ) )
 			return $groups;
 
+		// Maybe fetch field data
 		if ( ! empty( $fetch_field_data ) ) {
 
 			// Fetch the field data for the user.
@@ -184,11 +214,11 @@ class BP_XProfile_Group {
 			$field_ids_sql = implode( ',', (array) $field_ids );
 
 			if ( ! empty( $field_ids ) && ! empty( $user_id ) ) {
-				$field_data = $wpdb->get_results( $wpdb->prepare( "SELECT id, field_id, value FROM {$bp->profile->table_name_data} WHERE field_id IN ( {$field_ids_sql} ) AND user_id = %d", $user_id ) );
+				$field_data = BP_XProfile_ProfileData::get_data_for_user( $user_id, $field_ids );
 			}
 
 			// Remove data-less fields, if necessary
-			if ( !empty( $hide_empty_fields ) ) {
+			if ( !empty( $hide_empty_fields ) && ! empty( $field_ids ) && ! empty( $field_data ) ) {
 
 				// Loop through the results and find the fields that have data.
 				foreach( (array) $field_data as $data ) {
@@ -210,11 +240,10 @@ class BP_XProfile_Group {
 
 				// Reset indexes
 				$fields = array_values( $fields );
-
 			}
 
 			// Field data was found
-			if ( !empty( $field_data ) && !is_wp_error( $field_data ) ) {
+			if ( ! empty( $fields ) && !empty( $field_data ) && !is_wp_error( $field_data ) ) {
 
 				// Loop through fields
 				foreach( (array) $fields as $field_key => $field ) {
@@ -224,17 +253,26 @@ class BP_XProfile_Group {
 
 						// Assign correct data value to the field
 						if ( $field->id == $data->field_id ) {
-							$fields[$field_key]->data = new stdClass;
+							$fields[$field_key]->data        = new stdClass;
 							$fields[$field_key]->data->value = $data->value;
-							$fields[$field_key]->data->id = $data->id;
+							$fields[$field_key]->data->id    = $data->id;
 						}
+
+						// Store for meta cache priming
+						$object_ids['data'][] = $data->id;
 					}
 				}
 			}
+		}
 
-			if ( !empty( $fetch_visibility_level ) ) {
-				$fields = self::fetch_visibility_level( $user_id, $fields );
-			}
+		// Prime the meta cache, if necessary
+		if ( $update_meta_cache ) {
+			bp_xprofile_update_meta_cache( $object_ids );
+		}
+
+		// Maybe fetch visibility levels
+		if ( !empty( $fetch_visibility_level ) ) {
+			$fields = self::fetch_visibility_level( $user_id, $fields );
 		}
 
 		// Merge the field array back in with the group array
@@ -263,7 +301,64 @@ class BP_XProfile_Group {
 		return $groups;
 	}
 
-	function admin_validate() {
+	/**
+	 * Get data about a set of groups, based on IDs.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $group_ids Array of IDs.
+	 * @return array
+	 */
+	protected static function get_group_data( $group_ids ) {
+		global $wpdb;
+
+		// Bail if no group IDs are passed
+		if ( empty( $group_ids ) ) {
+			return array();
+		}
+
+		$groups        = array();
+		$uncached_gids = array();
+
+		foreach ( $group_ids as $group_id ) {
+
+			// If cached data is found, use it
+			if ( $group_data = wp_cache_get( 'xprofile_group_' . $group_id, 'bp' ) ) {
+				$groups[ $group_id ] = $group_data;
+
+			// Otherwise leave a placeholder so we don't lose the order
+			} else {
+				$groups[ $group_id ] = '';
+
+				// Add to the list of items to be queried
+				$uncached_gids[] = $group_id;
+			}
+		}
+
+		// Fetch uncached data from the DB if necessary
+		if ( ! empty( $uncached_gids ) ) {
+			$uncached_gids_sql = implode( ',', wp_parse_id_list( $uncached_gids ) );
+
+			$bp = buddypress();
+
+			// Fetch data, preserving order
+			$queried_gdata = $wpdb->get_results( "SELECT * FROM {$bp->profile->table_name_groups} WHERE id IN ({$uncached_gids_sql}) ORDER BY FIELD( id, {$uncached_gids_sql} )");
+
+			// Put queried data into the placeholders created earlier,
+			// and add it to the cache
+			foreach ( (array) $queried_gdata as $gdata ) {
+				$groups[ $gdata->id ] = $gdata;
+				wp_cache_set( 'xprofile_group_' . $gdata->id, $gdata, 'bp' );
+			}
+		}
+
+		// Reset indexes
+		$groups = array_values( $groups );
+
+		return $groups;
+	}
+
+	public static function admin_validate() {
 		global $message;
 
 		/* Validate Form */
@@ -275,7 +370,7 @@ class BP_XProfile_Group {
 		}
 	}
 
-	function update_position( $field_group_id, $position ) {
+	public static function update_position( $field_group_id, $position ) {
 		global $wpdb, $bp;
 
 		if ( !is_numeric( $position ) )
@@ -293,18 +388,15 @@ class BP_XProfile_Group {
 	 * @param array $fields The database results returned by the get() query
 	 * @return array $fields The database results, with field_visibility added
 	 */
-	function fetch_visibility_level( $user_id = 0, $fields = array() ) {
+	public static function fetch_visibility_level( $user_id = 0, $fields = array() ) {
 
 		// Get the user's visibility level preferences
 		$visibility_levels = bp_get_user_meta( $user_id, 'bp_xprofile_visibility_levels', true );
 
-		// Get the admin-set preferences
-		$admin_set_levels  = self::fetch_default_visibility_levels();
-
 		foreach( (array) $fields as $key => $field ) {
 
 			// Does the admin allow this field to be customized?
-			$allow_custom = empty( $admin_set_levels[$field->id]['allow_custom'] ) || 'allowed' == $admin_set_levels[$field->id]['allow_custom'];
+			$allow_custom = 'disabled' !== bp_xprofile_get_meta( $field->id, 'field', 'allow_custom_visibility' );
 
 			// Look to see if the user has set the visibility for this field
 			if ( $allow_custom && isset( $visibility_levels[$field->id] ) ) {
@@ -312,7 +404,8 @@ class BP_XProfile_Group {
 
 			// If no admin-set default is saved, fall back on a global default
 			} else {
-				$field_visibility = !empty( $admin_set_levels[$field->id]['default'] ) ? $admin_set_levels[$field->id]['default'] : apply_filters( 'bp_xprofile_default_visibility_level', 'public' );
+				$fallback_visibility = bp_xprofile_get_meta( $field->id, 'field', 'default_visibility' );
+				$field_visibility = ! empty( $fallback_visibility ) ? $fallback_visibility : apply_filters( 'bp_xprofile_default_visibility_level', 'public' );
 			}
 
 			$fields[$key]->visibility_level = $field_visibility;
@@ -322,32 +415,39 @@ class BP_XProfile_Group {
 	}
 
 	/**
-	 * Fetch the admin-set preferences for all fields
+	 * Fetch the admin-set preferences for all fields.
 	 *
-	 * @since BuddyPress (1.6)
+	 * @since BuddyPress (1.6.0)
 	 *
-	 * @return array $default_visibility_levels An array, keyed by field_id, of default
-	 *   visibility level + allow_custom (whether the admin allows this field to be set by user)
+	 * @return array $default_visibility_levels An array, keyed by
+	 *         field_id, of default visibility level + allow_custom
+	 *         (whether the admin allows this field to be set by user)
 	 */
-	function fetch_default_visibility_levels() {
+	public static function fetch_default_visibility_levels() {
 		global $wpdb, $bp;
 
-		$levels = $wpdb->get_results( "SELECT object_id, meta_key, meta_value FROM {$bp->profile->table_name_meta} WHERE object_type = 'field' AND ( meta_key = 'default_visibility' OR meta_key = 'allow_custom_visibility' )" );
+		$default_visibility_levels = wp_cache_get( 'xprofile_default_visibility_levels', 'bp' );
+
+		if ( false === $default_visibility_levels ) {
+			$levels = $wpdb->get_results( "SELECT object_id, meta_key, meta_value FROM {$bp->profile->table_name_meta} WHERE object_type = 'field' AND ( meta_key = 'default_visibility' OR meta_key = 'allow_custom_visibility' )" );
 
-		// Arrange so that the field id is the key and the visibility level the value
-		$default_visibility_levels = array();
-		foreach( $levels as $level ) {
-			if ( 'default_visibility' == $level->meta_key ) {
-				$default_visibility_levels[$level->object_id]['default'] = $level->meta_value;
-			} else if ( 'allow_custom_visibility' == $level->meta_key ) {
-				$default_visibility_levels[$level->object_id]['allow_custom'] = $level->meta_value;
+			// Arrange so that the field id is the key and the visibility level the value
+			$default_visibility_levels = array();
+			foreach ( $levels as $level ) {
+				if ( 'default_visibility' == $level->meta_key ) {
+					$default_visibility_levels[ $level->object_id ]['default'] = $level->meta_value;
+				} else if ( 'allow_custom_visibility' == $level->meta_key ) {
+					$default_visibility_levels[ $level->object_id ]['allow_custom'] = $level->meta_value;
+				}
 			}
+
+			wp_cache_set( 'xprofile_default_visibility_levels', $default_visibility_levels, 'bp' );
 		}
 
 		return $default_visibility_levels;
 	}
 
-	function render_admin_form() {
+	public function render_admin_form() {
 		global $message;
 
 		if ( empty( $this->id ) ) {
@@ -382,7 +482,7 @@ class BP_XProfile_Group {
 							<div id="titlediv">
 								<div id="titlewrap">
 									<label class="screen-reader-text" id="title-prompt-text" for=​"title">​<?php _e( 'Field Group Title', 'buddypress') ?></label>
-									<input type="text" name="group_name" id="title" value="<?php echo esc_attr( $this->name ); ?>" />
+									<input type="text" name="group_name" id="title" value="<?php echo esc_attr( $this->name ); ?>" placeholder="<?php esc_attr_e( 'Field Group Title', 'buddypress' ); ?>" />
 								</div>
 							</div>
 
@@ -426,31 +526,43 @@ class BP_XProfile_Group {
 }
 
 class BP_XProfile_Field {
-	var $id;
-	var $group_id;
-	var $parent_id;
-	var $type;
-	var $name;
-	var $description;
-	var $is_required;
-	var $can_delete;
-	var $field_order;
-	var $option_order;
-	var $order_by;
-	var $is_default_option;
-	var $default_visibility;
-	var $allow_custom_visibility = 'allowed';
-
-	var $data;
-	var $message = null;
-	var $message_type = 'err';
-
-	function __construct( $id = null, $user_id = null, $get_data = true ) {
-		if ( !empty( $id ) )
+	public $id;
+	public $group_id;
+	public $parent_id;
+	public $type;
+	public $name;
+	public $description;
+	public $is_required;
+	public $can_delete = '1';
+	public $field_order;
+	public $option_order;
+	public $order_by;
+	public $is_default_option;
+	public $default_visibility = 'public';
+	public $allow_custom_visibility = 'allowed';
+
+	/**
+	 * @since BuddyPress (2.0.0)
+	 * @var BP_XProfile_Field_Type Field type object used for validation
+	 */
+	public $type_obj = null;
+
+	public $data;
+	public $message = null;
+	public $message_type = 'err';
+
+	public function __construct( $id = null, $user_id = null, $get_data = true ) {
+		if ( !empty( $id ) ) {
 			$this->populate( $id, $user_id, $get_data );
+
+		// Initialise the type obj to prevent fatals when creating new profile fields
+		} else {
+			$this->type_obj            = bp_xprofile_create_field_type( 'textbox' );
+			$this->type_obj->field_obj = $this;
+		}
 	}
 
-	function populate( $id, $user_id, $get_data ) {
+	public function populate( $id, $user_id, $get_data ) {
 		global $wpdb, $userdata, $bp;
 
 		if ( empty( $user_id ) ) {
@@ -473,6 +585,10 @@ class BP_XProfile_Field {
 			$this->order_by          = $field->order_by;
 			$this->is_default_option = $field->is_default_option;
 
+			// Create the field type and store a reference back to this object.
+			$this->type_obj            = bp_xprofile_create_field_type( $field->type );
+			$this->type_obj->field_obj = $this;
+
 			if ( $get_data && $user_id ) {
 				$this->data          = $this->get_field_data( $user_id );
 			}
@@ -487,7 +603,7 @@ class BP_XProfile_Field {
 		}
 	}
 
-	function delete( $delete_data = false ) {
+	public function delete( $delete_data = false ) {
 		global $wpdb, $bp;
 
 		// Prevent deletion if no ID is present
@@ -506,24 +622,26 @@ class BP_XProfile_Field {
 		return true;
 	}
 
-	function save() {
+	public function save() {
 		global $wpdb, $bp;
 
-		$this->group_id	   = apply_filters( 'xprofile_field_group_id_before_save',    $this->group_id,    $this->id );
+		$this->group_id    = apply_filters( 'xprofile_field_group_id_before_save',    $this->group_id,    $this->id );
 		$this->parent_id   = apply_filters( 'xprofile_field_parent_id_before_save',   $this->parent_id,   $this->id );
-		$this->type	       = apply_filters( 'xprofile_field_type_before_save',        $this->type,        $this->id );
-		$this->name	       = apply_filters( 'xprofile_field_name_before_save',        $this->name,        $this->id );
+		$this->type        = apply_filters( 'xprofile_field_type_before_save',        $this->type,        $this->id );
+		$this->name        = apply_filters( 'xprofile_field_name_before_save',        $this->name,        $this->id );
 		$this->description = apply_filters( 'xprofile_field_description_before_save', $this->description, $this->id );
 		$this->is_required = apply_filters( 'xprofile_field_is_required_before_save', $this->is_required, $this->id );
 		$this->order_by	   = apply_filters( 'xprofile_field_order_by_before_save',    $this->order_by,    $this->id );
 		$this->field_order = apply_filters( 'xprofile_field_field_order_before_save', $this->field_order, $this->id );
+		$this->can_delete  = apply_filters( 'xprofile_field_can_delete_before_save',  $this->can_delete,  $this->id );
+		$this->type_obj    = bp_xprofile_create_field_type( $this->type );
 
 		do_action_ref_array( 'xprofile_field_before_save', array( $this ) );
 
 		if ( $this->id != null ) {
-			$sql = $wpdb->prepare( "UPDATE {$bp->profile->table_name_fields} SET group_id = %d, parent_id = 0, type = %s, name = %s, description = %s, is_required = %d, order_by = %s, field_order = %d WHERE id = %d", $this->group_id, $this->type, $this->name, $this->description, $this->is_required, $this->order_by, $this->field_order, $this->id );
+			$sql = $wpdb->prepare( "UPDATE {$bp->profile->table_name_fields} SET group_id = %d, parent_id = 0, type = %s, name = %s, description = %s, is_required = %d, order_by = %s, field_order = %d, can_delete = %d WHERE id = %d", $this->group_id, $this->type, $this->name, $this->description, $this->is_required, $this->order_by, $this->field_order, $this->can_delete, $this->id );
 		} else {
-			$sql = $wpdb->prepare( "INSERT INTO {$bp->profile->table_name_fields} (group_id, parent_id, type, name, description, is_required, order_by, field_order ) VALUES (%d, %d, %s, %s, %s, %d, %s, %d )", $this->group_id, $this->parent_id, $this->type, $this->name, $this->description, $this->is_required, $this->order_by, $this->field_order );
+			$sql = $wpdb->prepare( "INSERT INTO {$bp->profile->table_name_fields} (group_id, parent_id, type, name, description, is_required, order_by, field_order, can_delete ) VALUES (%d, %d, %s, %s, %s, %d, %s, %d, %d )", $this->group_id, $this->parent_id, $this->type, $this->name, $this->description, $this->is_required, $this->order_by, $this->field_order, $this->can_delete );
 		}
 
 		/**
@@ -554,7 +672,7 @@ class BP_XProfile_Field {
 			 * Check to see if this is a field with child options.
 			 * We need to add the options to the db, if it is.
 			 */
-			if ( 'radio' == $this->type || 'selectbox' == $this->type || 'checkbox' == $this->type || 'multiselectbox' == $this->type ) {
+			if ( $this->type_obj->supports_options ) {
 
 				if ( !empty( $this->id ) ) {
 					$parent_id = $this->id;
@@ -562,34 +680,11 @@ class BP_XProfile_Field {
 					$parent_id = $wpdb->insert_id;
 				}
 
-				if ( 'radio' == $this->type ) {
-					$post_option  = !empty( $_POST['radio_option']           ) ? $_POST['radio_option']           : '';
-					$post_default = !empty( $_POST['isDefault_radio_option'] ) ? $_POST['isDefault_radio_option'] : '';
-
-					$options	= apply_filters( 'xprofile_field_options_before_save', $post_option,  'radio' );
-					$defaults	= apply_filters( 'xprofile_field_default_before_save', $post_default, 'radio' );
-
-				} elseif ( 'selectbox' == $this->type ) {
-					$post_option  = !empty( $_POST['selectbox_option']           ) ? $_POST['selectbox_option']           : '';
-					$post_default = !empty( $_POST['isDefault_selectbox_option'] ) ? $_POST['isDefault_selectbox_option'] : '';
-
-					$options	= apply_filters( 'xprofile_field_options_before_save', $post_option, 'selectbox' );
-					$defaults	= apply_filters( 'xprofile_field_default_before_save', $post_default, 'selectbox' );
-
-				} elseif ( 'multiselectbox' == $this->type ) {
-					$post_option  = !empty( $_POST['multiselectbox_option']           ) ? $_POST['multiselectbox_option']           : '';
-					$post_default = !empty( $_POST['isDefault_multiselectbox_option'] ) ? $_POST['isDefault_multiselectbox_option'] : '';
-
-					$options	= apply_filters( 'xprofile_field_options_before_save', $post_option, 'multiselectbox' );
-					$defaults	= apply_filters( 'xprofile_field_default_before_save', $post_default, 'multiselectbox' );
-
-				} elseif ( 'checkbox' == $this->type ) {
-					$post_option  = !empty( $_POST['checkbox_option']           ) ? $_POST['checkbox_option']           : '';
-					$post_default = !empty( $_POST['isDefault_checkbox_option'] ) ? $_POST['isDefault_checkbox_option'] : '';
-
-					$options	= apply_filters( 'xprofile_field_options_before_save', $post_option, 'checkbox' );
-					$defaults	= apply_filters( 'xprofile_field_default_before_save', $post_default, 'checkbox' );
-				}
+				// Allow plugins to filter the field's child options (i.e. the items in a selectbox).
+				$post_option  = ! empty( $_POST["{$this->type}_option"] ) ? $_POST["{$this->type}_option"] : '';
+				$post_default = ! empty( $_POST["isDefault_{$this->type}_option"] ) ? $_POST["isDefault_{$this->type}_option"] : '';
+				$options      = apply_filters( 'xprofile_field_options_before_save', $post_option,  $this->type );
+				$defaults     = apply_filters( 'xprofile_field_default_before_save', $post_default, $this->type );
 
 				$counter = 1;
 				if ( !empty( $options ) ) {
@@ -617,17 +712,21 @@ class BP_XProfile_Field {
 
 			do_action_ref_array( 'xprofile_field_after_save', array( $this ) );
 
+			// Recreate type_obj in case someone changed $this->type via a filter
+	 		$this->type_obj            = bp_xprofile_create_field_type( $this->type );
+	 		$this->type_obj->field_obj = $this;
+
 			return $field_id;
 		} else {
 			return false;
 		}
 	}
 
-	function get_field_data( $user_id ) {
+	public function get_field_data( $user_id ) {
 		return new BP_XProfile_ProfileData( $this->id, $user_id );
 	}
 
-	function get_children( $for_editing = false ) {
+	public function get_children( $for_editing = false ) {
 		global $wpdb, $bp;
 
 		// This is done here so we don't have problems with sql injection
@@ -654,7 +753,7 @@ class BP_XProfile_Field {
 		return apply_filters( 'bp_xprofile_field_get_children', $children );
 	}
 
-	function delete_children() {
+	public function delete_children() {
 		global $wpdb, $bp;
 
 		$sql = $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_fields} WHERE parent_id = %d", $this->id );
@@ -662,9 +761,9 @@ class BP_XProfile_Field {
 		$wpdb->query( $sql );
 	}
 
-	/* Static Functions */
+	/** Static Methods ********************************************************/
 
-	function get_type( $field_id ) {
+	public static function get_type( $field_id ) {
 		global $wpdb, $bp;
 
 		if ( !empty( $field_id ) ) {
@@ -680,7 +779,7 @@ class BP_XProfile_Field {
 		return false;
 	}
 
-	function delete_for_group( $group_id ) {
+	public static function delete_for_group( $group_id ) {
 		global $wpdb, $bp;
 
 		if ( !empty( $group_id ) ) {
@@ -696,7 +795,7 @@ class BP_XProfile_Field {
 		return false;
 	}
 
-	function get_id_from_name( $field_name ) {
+	public static function get_id_from_name( $field_name ) {
 		global $wpdb, $bp;
 
 		if ( empty( $bp->profile->table_name_fields ) || !isset( $field_name ) )
@@ -705,7 +804,7 @@ class BP_XProfile_Field {
 		return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", $field_name ) );
 	}
 
-	function update_position( $field_id, $position, $field_group_id ) {
+	public static function update_position( $field_id, $position, $field_group_id ) {
 		global $wpdb, $bp;
 
 		if ( !is_numeric( $position ) || !is_numeric( $field_group_id ) )
@@ -723,97 +822,17 @@ class BP_XProfile_Field {
 		return false;
 	}
 
-	/* ADMIN AREA HTML.
-	* TODO: Get this out of here and replace with standard template loops
-	*/
-
-	/* This function populates the items for radio buttons checkboxes and drop down boxes */
-	function render_admin_form_children() {
-		$input_types = array( 'checkbox', 'selectbox', 'multiselectbox', 'radio' );
-
-		foreach ( $input_types as $type ) {
-			$default_name = '';
-
-			if ( ( 'multiselectbox' == $type ) || ( 'checkbox' == $type ) ) {
-				$default_input = 'checkbox';
-			} else {
-				$default_input = 'radio';
-			}
-
-			$class = $this->type != $type ? 'display: none;' : '';
-
-			if ( empty( $this->default_visibility ) ) {
-				$this->default_visibility = 'public';
-			}
-
-			?>
-
-			<div id="<?php echo esc_attr( $type ); ?>" class="options-box" style="<?php echo esc_attr( $class ); ?> margin-left: 15px;">
-				<h4><?php _e( 'Please enter options for this Field:', 'buddypress' ); ?></h4>
-				<p>
-					<label for="sort_order_<?php echo esc_attr( $type ); ?>"><?php _e( 'Sort Order:', 'buddypress' ); ?></label>
-					<select name="sort_order_<?php echo esc_attr( $type ); ?>" id="sort_order_<?php echo esc_attr( $type ); ?>" >
-						<option value="custom" <?php selected( 'custom', $this->order_by ); ?>><?php _e( 'Custom',     'buddypress' ); ?></option>
-						<option value="asc"    <?php selected( 'asc',    $this->order_by ); ?>><?php _e( 'Ascending',  'buddypress' ); ?></option>
-						<option value="desc"   <?php selected( 'desc',   $this->order_by ); ?>><?php _e( 'Descending', 'buddypress' ); ?></option>
-					</select>
-
-				<?php if ( !$options = $this->get_children( true ) ) {
-
-					$i = 1;
-					while ( isset( $_POST[$type . '_option'][$i] ) ) {
-						(array) $options[] = (object) array(
-							'id'                => -1,
-							'name'              => $_POST[$type . '_option'][$i],
-							'is_default_option' => ( ( 'multiselectbox' != $type ) && ( 'checkbox' != $type ) && ( $_POST["isDefault_{$type}_option"] == $i ) ) ? 1 : $_POST["isDefault_{$type}_option"][$i]
-						);
-
-						++$i;
-					}
-				}
-
-				if ( !empty( $options ) ) {
-					for ( $i = 0, $count = count( $options ); $i < $count; ++$i ) {
-						$j = $i + 1;
-
-						if ( 'multiselectbox' == $type || 'checkbox' == $type )
-							$default_name = '[' . $j . ']'; ?>
-
-						<p class="sortable">
-							<span>&nbsp;&Xi;&nbsp;</span>
-							<input type="text" name="<?php echo esc_attr( $type ); ?>_option[<?php echo esc_attr( $j ); ?>]" id="<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $j ); ?>" value="<?php echo stripslashes( esc_attr( $options[$i]->name ) ); ?>" />
-							<input type="<?php echo $default_input; ?>" name="isDefault_<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $default_name ); ?>" <?php checked( (int) $options[$i]->is_default_option, true ); ?> value="<?php echo esc_attr( $j ); ?>" />
-							<span><?php _e( 'Default Value', 'buddypress' ); ?></span>
-							<a href="<?php echo esc_url( 'users.php?page=bp-profile-setup&amp;mode=delete_option&amp;option_id=' . $options[$i]->id ); ?>" class="ajax-option-delete" id="delete-<?php echo esc_attr( $options[$i]->id ); ?>">[x]</a>
-						</p>
-
-					<?php } /* end for */ ?>
-
-					<input type="hidden" name="<?php echo esc_attr( $type ); ?>_option_number" id="<?php echo esc_attr( $type ); ?>_option_number" value="<?php echo esc_attr( (int) $j + 1 ); ?>" />
-
-				<?php } else {
-
-					if ( 'multiselectbox' == $type || 'checkbox' == $type )
-						$default_name = '[1]'; ?>
-
-					<p class="sortable">
-						<span>&nbsp;&Xi;&nbsp;</span>
-						<input type="text" name="<?php echo esc_attr( $type ); ?>_option[1]" id="<?php echo esc_attr( $type ); ?>_option1" />
-						<input type="<?php echo esc_attr( $default_input ); ?>" name="isDefault_<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $default_name ); ?>" id="isDefault_<?php echo esc_attr( $type ); ?>_option" value="1" />
-						<span><?php _e( 'Default Value', 'buddypress' ); ?></span>
-						<input type="hidden" name="<?php echo esc_attr( $type ); ?>_option_number" id="<?php echo esc_attr( $type ); ?>_option_number" value="2" />
-					</p>
-
-				<?php } /* end if */ ?>
-
-				<div id="<?php echo esc_attr( $type ); ?>_more"></div>
-				<p><a href="javascript:add_option('<?php echo esc_attr( $type ); ?>')"><?php _e( 'Add Another Option', 'buddypress' ); ?></a></p>
-			</div>
-
-		<?php }
+	/**
+	 * This function populates the items for radio buttons checkboxes and drop down boxes
+	 */
+	public function render_admin_form_children() {
+		foreach ( array_keys( bp_xprofile_get_field_types() ) as $field_type ) {
+			$type_obj = bp_xprofile_create_field_type( $field_type );
+			$type_obj->admin_new_field_html( $this );
+		}
 	}
 
-	function render_admin_form( $message = '' ) {
+	public function render_admin_form( $message = '' ) {
 		if ( empty( $this->id ) ) {
 			$title  = __( 'Add Field', 'buddypress' );
 			$action	= "users.php?page=bp-profile-setup&amp;group_id=" . $this->group_id . "&amp;mode=add_field#tabs-" . $this->group_id;
@@ -834,7 +853,6 @@ class BP_XProfile_Field {
 		<div class="wrap">
 			<div id="icon-users" class="icon32"><br /></div>
 			<h2><?php echo esc_html( $title ); ?></h2>
-			<p><?php _e( 'Fields marked * are required', 'buddypress' ) ?></p>
 
 			<?php if ( !empty( $message ) ) : ?>
 
@@ -846,91 +864,121 @@ class BP_XProfile_Field {
 
 			<form id="bp-xprofile-add-field" action="<?php echo esc_url( $action ); ?>" method="post">
 				<div id="poststuff">
-					<div id="titlediv">
-						<h3><label for="title"><?php _e( 'Field Title', 'buddypress' ); ?> *</label></h3>
-						<div id="titlewrap">
-							<input type="text" name="title" id="title" value="<?php echo esc_attr( $this->name ); ?>" style="width:50%" />
-						</div>
-					</div>
+					<div id="post-body" class="metabox-holder columns-<?php echo ( 1 == get_current_screen()->get_columns() ) ? '1' : '2'; ?>">
+						<div id="post-body-content">
+							<div id="titlediv">
+								<input type="text" name="title" id="title" value="<?php echo esc_attr( $this->name ); ?>" />
+							</div>
+							<div class="postbox">
+								<h3><?php _e( 'Field Description', 'buddypress' ); ?></h3>
+								<div class="inside">
+									<textarea name="description" id="description" rows="8" cols="60"><?php echo esc_textarea( $this->description ); ?></textarea>
+								</div>
+							</div>
+						</div><!-- #post-body-content -->
 
-					<div id="titlediv">
-						<h3><label for="description"><?php _e("Field Description", 'buddypress'); ?></label></h3>
-						<div id="titlewrap">
-							<textarea name="description" id="description" rows="8" cols="60"><?php echo esc_textarea( $this->description ); ?></textarea>
-						</div>
-					</div>
+						<div id="postbox-container-1" class="postbox-container">
+							<div id="submitdiv" class="postbox">
+								<h3><?php _e( 'Submit', 'buddypress' ); ?></h3>
+								<div class="inside">
+									<div id="submitcomment" class="submitbox">
+										<div id="major-publishing-actions">
+											<input type="hidden" name="field_order" id="field_order" value="<?php echo esc_attr( $this->field_order ); ?>" />
+											<div id="publishing-action">
+												<input type="submit" value="<?php esc_attr_e( 'Save', 'buddypress' ); ?>" name="saveField" id="saveField" style="font-weight: bold" class="button-primary" />
+											</div>
+											<div id="delete-action">
+												<a href="users.php?page=bp-profile-setup" class="deletion"><?php _e( 'Cancel', 'buddypress' ); ?></a>
+											</div>
+											<?php wp_nonce_field( 'xprofile_delete_option' ); ?>
+											<div class="clear"></div>
+										</div>
+									</div>
+								</div>
+							</div>
 
-					<?php if ( '0' != $this->can_delete ) : ?>
+							<?php /* Field 1 is the fullname field, which cannot have custom visibility */ ?>
+							<?php if ( 1 != $this->id ) : ?>
 
-						<div id="titlediv">
-							<h3><label for="required"><?php _e( "Is This Field Required?", 'buddypress' ); ?> *</label></h3>
-							<select name="required" id="required" style="width: 30%">
-								<option value="0"<?php selected( $this->is_required, '0' ); ?>><?php _e( 'Not Required', 'buddypress' ); ?></option>
-								<option value="1"<?php selected( $this->is_required, '1' ); ?>><?php _e( 'Required',     'buddypress' ); ?></option>
-							</select>
-						</div>
+								<div class="postbox">
+									<h3><label for="default-visibility"><?php _e( 'Default Visibility', 'buddypress' ); ?></label></h3>
+									<div class="inside">
+										<ul>
 
-						<div id="titlediv">
-							<h3><label for="fieldtype"><?php _e( 'Field Type', 'buddypress'); ?> *</label></h3>
-							<select name="fieldtype" id="fieldtype" onchange="show_options(this.value)" style="width: 30%">
-								<option value="textbox"        <?php selected( $this->type, 'textbox'        ); ?>><?php _e( 'Text Box',             'buddypress' ); ?></option>
-								<option value="textarea"       <?php selected( $this->type, 'textarea'       ); ?>><?php _e( 'Multi-line Text Box',  'buddypress' ); ?></option>
-								<option value="datebox"        <?php selected( $this->type, 'datebox'        ); ?>><?php _e( 'Date Selector',        'buddypress' ); ?></option>
-								<option value="radio"          <?php selected( $this->type, 'radio'          ); ?>><?php _e( 'Radio Buttons',        'buddypress' ); ?></option>
-								<option value="selectbox"      <?php selected( $this->type, 'selectbox'      ); ?>><?php _e( 'Drop Down Select Box', 'buddypress' ); ?></option>
-								<option value="multiselectbox" <?php selected( $this->type, 'multiselectbox' ); ?>><?php _e( 'Multi Select Box',     'buddypress' ); ?></option>
-								<option value="checkbox"       <?php selected( $this->type, 'checkbox'       ); ?>><?php _e( 'Checkboxes',           'buddypress' ); ?></option>
-							</select>
-						</div>
+											<?php foreach( bp_xprofile_get_visibility_levels() as $level ) : ?>
 
-						<?php do_action_ref_array( 'xprofile_field_additional_options', array( $this ) ); ?>
+												<li>
+													<input type="radio" id="default-visibility[<?php echo esc_attr( $level['id'] ) ?>]" name="default-visibility" value="<?php echo esc_attr( $level['id'] ) ?>" <?php checked( $this->default_visibility, $level['id'] ); ?> />
+													<label for="default-visibility[<?php echo esc_attr( $level['id'] ) ?>]"><?php echo esc_html( $level['label'] ) ?></label>
+												</li>
 
-						<?php $this->render_admin_form_children(); ?>
+											<?php endforeach ?>
 
-					<?php else : ?>
+										</ul>
+									</div>
+								</div>
 
-						<input type="hidden" name="required"  id="required"  value="1"       />
-						<input type="hidden" name="fieldtype" id="fieldtype" value="textbox" />
+								<div class="postbox">
+									<h3><label for="allow-custom-visibility"><?php _e( 'Per-Member Visibility', 'buddypress' ); ?></label></h3>
+									<div class="inside">
+										<ul>
+											<li>
+												<input type="radio" id="allow-custom-visibility-allowed" name="allow-custom-visibility" value="allowed" <?php checked( $this->allow_custom_visibility, 'allowed' ); ?> />
+												<label for="allow-custom-visibility-allowed"><?php _e( "Let members change this field's visibility", 'buddypress' ); ?></label>
+											</li>
+											<li>
+												<input type="radio" id="allow-custom-visibility-disabled" name="allow-custom-visibility" value="disabled" <?php checked( $this->allow_custom_visibility, 'disabled' ); ?> />
+												<label for="allow-custom-visibility-disabled"><?php _e( 'Enforce the default visibility for all members', 'buddypress' ); ?></label>
+											</li>
+										</ul>
+									</div>
+								</div>
 
-					<?php endif;
+							<?php endif ?>
+						</div>
 
-					/* The fullname field cannot be hidden */
-					if ( 1 != $this->id ) : ?>
+						<div id="postbox-container-2" class="postbox-container">
 
-						<div id="titlediv">
-							<div id="titlewrap">
-								<h3><label for="default-visibility"><?php _e( 'Default Visibility', 'buddypress' ); ?></label></h3>
-								<ul>
+							<?php /* Field 1 is the fullname field, which cannot be altered */ ?>
+							<?php if ( 1 != $this->id ) : ?>
 
-									<?php foreach( bp_xprofile_get_visibility_levels() as $level ) : ?>
+								<div class="postbox">
+									<h3><label for="required"><?php _e( "Field Requirement", 'buddypress' ); ?></label></h3>
+									<div class="inside">
+										<select name="required" id="required" style="width: 30%">
+											<option value="0"<?php selected( $this->is_required, '0' ); ?>><?php _e( 'Not Required', 'buddypress' ); ?></option>
+											<option value="1"<?php selected( $this->is_required, '1' ); ?>><?php _e( 'Required',     'buddypress' ); ?></option>
+										</select>
+									</div>
+								</div>
 
-										<li><label><input type="radio" name="default-visibility" value="<?php echo esc_attr( $level['id'] ) ?>" <?php checked( $this->default_visibility, $level['id'] ); ?>> <?php echo esc_html( $level['label'] ) ?></label></li>
+								<div class="postbox">
+									<h3><label for="fieldtype"><?php _e( 'Field Type', 'buddypress'); ?></label></h3>
+									<div class="inside">
+										<select name="fieldtype" id="fieldtype" onchange="show_options(this.value)" style="width: 30%">
+											<?php bp_xprofile_admin_form_field_types( $this->type ); ?>
+										</select>
 
-									<?php endforeach ?>
+										<?php
+										// Deprecated filter, don't use. Go look at {@link BP_XProfile_Field_Type::admin_new_field_html()}.
+										do_action( 'xprofile_field_additional_options', $this );
 
-								</ul>
-							</div>
+										$this->render_admin_form_children();
+										?>
+									</div>
+								</div>
 
-							<div id="titlewrap">
-								<h3><label for="allow-custom-visibility"><?php _e( 'Per-Member Visibility', 'buddypress' ); ?></label></h3>
-								<ul>
-									<li><label><input type="radio" name="allow-custom-visibility" value="allowed"  <?php checked( $this->allow_custom_visibility, 'allowed'  ); ?>> <?php _e( "Let members change this field's visibility", 'buddypress' ); ?></label></li>
-									<li><label><input type="radio" name="allow-custom-visibility" value="disabled" <?php checked( $this->allow_custom_visibility, 'disabled' ); ?>> <?php _e( 'Enforce the default visibility for all members', 'buddypress' ); ?></label></li>
-								</ul>
-							</div>
-						</div>
+							<?php else : ?>
 
-					<?php endif ?>
+								<input type="hidden" name="required"  id="required"  value="1"       />
+								<input type="hidden" name="fieldtype" id="fieldtype" value="textbox" />
 
-					<p class="submit">
-						<input type="hidden" name="field_order" id="field_order" value="<?php echo esc_attr( $this->field_order ); ?>" />
-						<input type="submit" value="<?php _e( 'Save', 'buddypress' ); ?>" name="saveField" id="saveField" style="font-weight: bold" class="button-primary" />
-						<?php _e( 'or', 'buddypress' ); ?> <a href="users.php?page=bp-profile-setup" class="deletion"><?php _e( 'Cancel', 'buddypress' ); ?></a>
-					</p>
+							<?php endif; ?>
 
-				</div>
+						</div>
+					</div><!-- #post-body -->
 
-				<?php wp_nonce_field( 'xprofile_delete_option' ); ?>
+				</div><!-- #poststuff -->
 
 			</form>
 		</div>
@@ -938,56 +986,63 @@ class BP_XProfile_Field {
 <?php
 	}
 
-	function admin_validate() {
+	public static function admin_validate() {
 		global $message;
 
 		// Validate Form
 		if ( '' == $_POST['title'] || '' == $_POST['required'] || '' == $_POST['fieldtype'] ) {
 			$message = __( 'Please make sure you fill out all required fields.', 'buddypress' );
 			return false;
-		} else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'radio' && empty( $_POST['radio_option'][1] ) ) {
-			$message = __( 'Radio button field types require at least one option. Please add options below.', 'buddypress' );
-			return false;
-		} else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'selectbox' && empty( $_POST['selectbox_option'][1] ) ) {
-			$message = __( 'Select box field types require at least one option. Please add options below.', 'buddypress' );
-			return false;
-		} else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'multiselectbox' && empty( $_POST['multiselectbox_option'][1] ) ) {
-			$message = __( 'Select box field types require at least one option. Please add options below.', 'buddypress' );
-			return false;
-		} else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'checkbox' && empty( $_POST['checkbox_option'][1] ) ) {
-			$message = __( 'Checkbox field types require at least one option. Please add options below.', 'buddypress' );
-			return false;
-		} else {
-			return true;
+
+		} elseif ( empty( $_POST['field_file'] ) ) {
+			$field_type  = bp_xprofile_create_field_type( $_POST['fieldtype'] );
+			$option_name = "{$_POST['fieldtype']}_option";
+
+			if ( $field_type->supports_options && isset( $_POST[$option_name] ) && empty( $_POST[$option_name][1] ) ) {
+				$message = __( 'This field type require at least one option. Please add options below.', 'buddypress' );
+				return false;
+			} 
 		}
+
+		return true;
 	}
 }
 
-
 class BP_XProfile_ProfileData {
-	var $id;
-	var $user_id;
-	var $field_id;
-	var $value;
-	var $last_updated;
+	public $id;
+	public $user_id;
+	public $field_id;
+	public $value;
+	public $last_updated;
 
-	function __construct( $field_id = null, $user_id = null ) {
+	public function __construct( $field_id = null, $user_id = null ) {
 		if ( !empty( $field_id ) ) {
 			$this->populate( $field_id, $user_id );
 		}
 	}
 
-	function populate( $field_id, $user_id )  {
+	public function populate( $field_id, $user_id )  {
 		global $wpdb, $bp;
 
-		$sql = $wpdb->prepare( "SELECT * FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $field_id, $user_id );
+		$cache_group = 'bp_xprofile_data_' . $user_id;
+		$profiledata = wp_cache_get( $field_id, $cache_group );
+
+		if ( false === $profiledata ) {
+			$sql = $wpdb->prepare( "SELECT * FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $field_id, $user_id );
+			$profiledata = $wpdb->get_row( $sql );
 
-		if ( $profiledata = $wpdb->get_row( $sql ) ) {
+			if ( $profiledata ) {
+				wp_cache_set( $field_id, $profiledata, $cache_group );
+			}
+		}
+
+		if ( $profiledata ) {
 			$this->id           = $profiledata->id;
 			$this->user_id      = $profiledata->user_id;
 			$this->field_id     = $profiledata->field_id;
 			$this->value        = stripslashes( $profiledata->value );
 			$this->last_updated = $profiledata->last_updated;
+
 		} else {
 			// When no row is found, we'll need to set these properties manually
 			$this->field_id	    = $field_id;
@@ -996,32 +1051,35 @@ class BP_XProfile_ProfileData {
 	}
 
 	/**
-	 * exists ()
-	 *
 	 * Check if there is data already for the user.
 	 *
 	 * @global object $wpdb
 	 * @global array $bp
 	 * @return bool
 	 */
-	function exists() {
+	public function exists() {
 		global $wpdb, $bp;
 
-		$retval = $wpdb->get_row( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_data} WHERE user_id = %d AND field_id = %d", $this->user_id, $this->field_id ) );
+		// Check cache first
+		$cached = wp_cache_get( $this->field_id, 'bp_xprofile_data_' . $this->user_id );
+
+		if ( $cached && ! empty( $cached->id ) ) {
+			$retval = true;
+		} else {
+			$retval = $wpdb->get_row( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_data} WHERE user_id = %d AND field_id = %d", $this->user_id, $this->field_id ) );
+		}
 
 		return apply_filters_ref_array( 'xprofile_data_exists', array( (bool)$retval, $this ) );
 	}
 
 	/**
-	 * is_valid_field()
-	 *
 	 * Check if this data is for a valid field.
 	 *
 	 * @global object $wpdb
 	 * @global array $bp
 	 * @return bool
 	 */
-	function is_valid_field() {
+	public function is_valid_field() {
 		global $wpdb, $bp;
 
 		$retval = $wpdb->get_row( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE id = %d", $this->field_id ) );
@@ -1029,7 +1087,7 @@ class BP_XProfile_ProfileData {
 		return apply_filters_ref_array( 'xprofile_data_is_valid_field', array( (bool)$retval, $this ) );
 	}
 
-	function save() {
+	public function save() {
 		global $wpdb, $bp;
 
 		$this->user_id      = apply_filters( 'xprofile_data_user_id_before_save',      $this->user_id,         $this->id );
@@ -1040,7 +1098,7 @@ class BP_XProfile_ProfileData {
 		do_action_ref_array( 'xprofile_data_before_save', array( $this ) );
 
 		if ( $this->is_valid_field() ) {
-			if ( $this->exists() && !empty( $this->value ) && strlen( trim( $this->value ) ) ) {
+			if ( $this->exists() && strlen( trim( $this->value ) ) ) {
 				$result   = $wpdb->query( $wpdb->prepare( "UPDATE {$bp->profile->table_name_data} SET value = %s, last_updated = %s WHERE user_id = %d AND field_id = %d", $this->value, $this->last_updated, $this->user_id, $this->field_id ) );
 
 			} else if ( $this->exists() && empty( $this->value ) ) {
@@ -1063,41 +1121,132 @@ class BP_XProfile_ProfileData {
 		return false;
 	}
 
-	function delete() {
-		global $wpdb, $bp;
+	/**
+	 * Delete specific XProfile field data
+	 *
+	 * @global object $wpdb
+	 * @return boolean
+	 */
+	public function delete() {
+		global $wpdb;
+
+		$bp = buddypress();
+
+		do_action_ref_array( 'xprofile_data_before_delete', array( $this ) );
 
 		if ( !$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $this->field_id, $this->user_id ) ) )
 			return false;
 
+		do_action_ref_array( 'xprofile_data_after_delete', array( $this ) );
+
 		return true;
 	}
 
-	/** Static Functions **/
+	/** Static Methods ********************************************************/
 
 	/**
-	 * BP_XProfile_ProfileData::get_all_for_user()
+	 * Get a user's profile data for a set of fields.
 	 *
+	 * @param int $user_id
+	 * @param array $field_ids
+	 * @return array
+	 */
+	public static function get_data_for_user( $user_id, $field_ids ) {
+		global $wpdb;
+
+		$data = array();
+
+		$cache_group = 'bp_xprofile_data_' . $user_id;
+
+		$uncached_field_ids = bp_get_non_cached_ids( $field_ids, $cache_group );
+
+		// Prime the cache
+		if ( ! empty( $uncached_field_ids ) ) {
+			$bp = buddypress();
+			$uncached_field_ids_sql = implode( ',', wp_parse_id_list( $uncached_field_ids ) );
+			$uncached_data = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, field_id, value, last_updated FROM {$bp->profile->table_name_data} WHERE field_id IN ({$uncached_field_ids_sql}) AND user_id = %d", $user_id ) );
+
+			// Rekey
+			$queried_data = array();
+			foreach ( $uncached_data as $ud ) {
+				$d               = new stdClass;
+				$d->id           = $ud->id;
+				$d->user_id      = $ud->user_id;
+				$d->field_id     = $ud->field_id;
+				$d->value        = $ud->value;
+				$d->last_updated = $ud->last_updated;
+
+				$queried_data[ $ud->field_id ] = $d;
+			}
+
+			// Set caches
+			foreach ( $uncached_field_ids as $field_id ) {
+
+				// If a value was found, cache it
+				if ( isset( $queried_data[ $field_id ] ) ) {
+					wp_cache_set( $field_id, $queried_data[ $field_id ], $cache_group );
+
+				// If no value was found, cache an empty item
+				// to avoid future cache misses
+				} else {
+					$d           = new stdClass;
+					$d->id       = '';
+					$d->field_id = $field_id;
+					$d->value    = '';
+
+					wp_cache_set( $field_id, $d, $cache_group );
+				}
+			}
+		}
+
+		// Now that all items are cached, fetch them
+		foreach ( $field_ids as $field_id ) {
+			$data[] = wp_cache_get( $field_id, $cache_group );
+		}
+
+		return $data;
+	}
+
+	/**
 	 * Get all of the profile information for a specific user.
+	 *
+	 * @param int $user_id ID of the user.
+	 * @return array
 	 */
-	function get_all_for_user( $user_id ) {
+	public static function get_all_for_user( $user_id ) {
 		global $wpdb, $bp;
 
-		$results      = $wpdb->get_results( $wpdb->prepare( "SELECT g.id as field_group_id, g.name as field_group_name, f.id as field_id, f.name as field_name, f.type as field_type, d.value as field_data, u.user_login, u.user_nicename, u.user_email FROM {$bp->profile->table_name_groups} g LEFT JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id INNER JOIN {$bp->profile->table_name_data} d ON f.id = d.field_id LEFT JOIN {$wpdb->users} u ON d.user_id = u.ID WHERE d.user_id = %d AND d.value != ''", $user_id ) );
+		$groups = BP_XProfile_Group::get( array(
+			'user_id'                => $user_id,
+			'hide_empty_groups'      => true,
+			'hide_empty_fields'      => true,
+			'fetch_fields'           => true,
+			'fetch_field_data'       => true,
+		) );
+
 		$profile_data = array();
 
-		if ( !empty( $results ) ) {
-			$profile_data['user_login']    = $results[0]->user_login;
-			$profile_data['user_nicename'] = $results[0]->user_nicename;
-			$profile_data['user_email']    = $results[0]->user_email;
-
-			foreach( (array) $results as $field ) {
-				$profile_data[$field->field_name] = array(
-					'field_group_id'   => $field->field_group_id,
-					'field_group_name' => $field->field_group_name,
-					'field_id'         => $field->field_id,
-					'field_type'       => $field->field_type,
-					'field_data'       => $field->field_data
-				);
+		if ( ! empty( $groups ) ) {
+			$user = new WP_User( $user_id );
+
+			$profile_data['user_login']    = $user->user_login;
+			$profile_data['user_nicename'] = $user->user_nicename;
+			$profile_data['user_email']    = $user->user_email;
+
+			foreach ( (array) $groups as $group ) {
+				if ( empty( $group->fields ) ) {
+					continue;
+				}
+
+				foreach ( (array) $group->fields as $field ) {
+					$profile_data[ $field->name ] = array(
+						'field_group_id'   => $group->id,
+						'field_group_name' => $group->name,
+						'field_id'         => $field->id,
+						'field_type'       => $field->type,
+						'field_data'       => $field->data->value,
+					);
+				}
 			}
 		}
 
@@ -1105,41 +1254,110 @@ class BP_XProfile_ProfileData {
 	}
 
 	/**
-	 * Get the user's field data id by the id of the xprofile field
+	 * Get the user's field data id by the id of the xprofile field.
 	 *
 	 * @param int $field_id
 	 * @param int $user_id
 	 * @return int $fielddata_id
 	 */
-	function get_fielddataid_byid( $field_id, $user_id ) {
+	public static function get_fielddataid_byid( $field_id, $user_id ) {
 		global $wpdb, $bp;
 
 		if ( empty( $field_id ) || empty( $user_id ) ) {
 			$fielddata_id = 0;
 		} else {
-			$fielddata_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $field_id, $user_id ) );
+
+			// Check cache first
+			$fielddata = wp_cache_get( $field_id, 'bp_xprofile_data_' . $user_id );
+			if ( false === $fielddata || empty( $fielddata->id ) ) {
+				$fielddata_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $field_id, $user_id ) );
+			} else {
+				$fielddata_id = $fielddata->id;
+			}
 		}
 
 		return $fielddata_id;
 	}
 
-	function get_value_byid( $field_id, $user_ids = null ) {
+	/**
+	 * Get profile field values by field ID and user IDs.
+	 *
+	 * Supports multiple user IDs.
+	 *
+	 * @param int $field_id ID of the field.
+	 * @param int|array $user_ids ID or IDs of user(s).
+	 * @return string|array Single value if a single user is queried,
+	 *         otherwise an array of results.
+	 */
+	public static function get_value_byid( $field_id, $user_ids = null ) {
 		global $wpdb, $bp;
 
-		if ( empty( $user_ids ) )
+		if ( empty( $user_ids ) ) {
 			$user_ids = bp_displayed_user_id();
+		}
 
-		if ( is_array( $user_ids ) ) {
-			$user_ids = implode( ',', wp_parse_id_list( $user_ids ) );
-			$data = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, value FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id IN ({$user_ids})", $field_id ) );
-		} else {
-			$data = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $field_id, $user_ids ) );
+		$is_single = false;
+		if ( ! is_array( $user_ids ) ) {
+			$user_ids  = array( $user_ids );
+			$is_single = true;
 		}
 
-		return $data;
+		// Assemble uncached IDs
+		$uncached_ids = array();
+		foreach ( $user_ids as $user_id ) {
+			if ( false === wp_cache_get( $field_id, 'bp_xprofile_data_' . $user_id ) ) {
+				$uncached_ids[] = $user_id;
+			}
+		}
+
+		// Prime caches
+		if ( ! empty( $uncached_ids ) ) {
+			$uncached_ids_sql = implode( ',', $uncached_ids );
+			$queried_data = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, field_id, value, last_updated FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id IN ({$uncached_ids_sql})", $field_id ) );
+
+			// Rekey
+			$qd = array();
+			foreach ( $queried_data as $data ) {
+				$qd[ $data->user_id ] = $data;
+			}
+
+			foreach ( $uncached_ids as $id ) {
+				// The value was successfully fetched
+				if ( isset( $qd[ $id ] ) ) {
+					$d = $qd[ $id ];
+
+				// No data found for the user, so we fake it to
+				// avoid cache misses and PHP notices
+				} else {
+					$d = new stdClass;
+					$d->id           = '';
+					$d->user_id      = $id;
+					$d->field_id     = '';
+					$d->value        = '';
+					$d->last_updated = '';
+				}
+
+				wp_cache_set( $field_id, $d, 'bp_xprofile_data_' . $d->user_id );
+			}
+		}
+
+		// Now that the cache is primed with all data, fetch it
+		$data = array();
+		foreach ( $user_ids as $user_id ) {
+			$data[] = wp_cache_get( $field_id, 'bp_xprofile_data_' . $user_id );
+		}
+
+		// If a single ID was passed, just return the value
+		if ( $is_single ) {
+			return $data[0]->value;
+
+		// Otherwise return the whole array
+		} else {
+			return $data;
+		}
 	}
 
-	function get_value_byfieldname( $fields, $user_id = null ) {
+	public static function get_value_byfieldname( $fields, $user_id = null ) {
 		global $bp, $wpdb;
 
 		if ( empty( $fields ) )
@@ -1188,7 +1406,7 @@ class BP_XProfile_ProfileData {
 		return $new_values;
 	}
 
-	function delete_for_field( $field_id ) {
+	public static function delete_for_field( $field_id ) {
 		global $wpdb, $bp;
 
 		if ( !$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_data} WHERE field_id = %d", $field_id ) ) )
@@ -1197,7 +1415,7 @@ class BP_XProfile_ProfileData {
 		return true;
 	}
 
-	function get_last_updated( $user_id ) {
+	public static function get_last_updated( $user_id ) {
 		global $wpdb, $bp;
 
 		$last_updated = $wpdb->get_var( $wpdb->prepare( "SELECT last_updated FROM {$bp->profile->table_name_data} WHERE user_id = %d ORDER BY last_updated LIMIT 1", $user_id ) );
@@ -1205,29 +1423,1409 @@ class BP_XProfile_ProfileData {
 		return $last_updated;
 	}
 
-	function delete_data_for_user( $user_id ) {
+	public static function delete_data_for_user( $user_id ) {
 		global $wpdb, $bp;
 
 		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_data} WHERE user_id = %d", $user_id ) );
 	}
 
-	function get_random( $user_id, $exclude_fullname ) {
+	public static function get_random( $user_id, $exclude_fullname ) {
 		global $wpdb, $bp;
 
-		if ( !empty( $exclude_fullname ) )
-			$exclude_sql = $wpdb->prepare( " AND pf.id != 1" );
+		$exclude_sql = ! empty( $exclude_fullname ) ? ' AND pf.id != 1' : '';
 
 		return $wpdb->get_results( $wpdb->prepare( "SELECT pf.type, pf.name, pd.value FROM {$bp->profile->table_name_data} pd INNER JOIN {$bp->profile->table_name_fields} pf ON pd.field_id = pf.id AND pd.user_id = %d {$exclude_sql} ORDER BY RAND() LIMIT 1", $user_id ) );
 	}
 
-	function get_fullname( $user_id = 0 ) {
+	public static function get_fullname( $user_id = 0 ) {
 
 		if ( empty( $user_id ) )
 			$user_id = bp_displayed_user_id();
 
-		$field_name = bp_xprofile_fullname_field_name();
-		$data       = xprofile_get_field_data( $field_name, $user_id );
+		$data = xprofile_get_field_data( bp_xprofile_fullname_field_id(), $user_id );
 
 		return $data[$field_name];
 	}
 }
+
+/**
+ * Datebox xprofile field type.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_Field_Type_Datebox extends BP_XProfile_Field_Type {
+
+	/**
+	 * Constructor for the datebox field type
+	 *
+	 * @since BuddyPress (2.0.0)
+ 	 */
+	public function __construct() {
+		parent::__construct();
+
+		$this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Date Selector', 'xprofile field type', 'buddypress' );
+
+		$this->set_format( '/^\d{4}-\d{1,2}-\d{1,2} 00:00:00$/', 'replace' );  // "Y-m-d 00:00:00"
+		do_action( 'bp_xprofile_field_type_datebox', $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.html permitted attributes} that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+		$user_id = bp_displayed_user_id();
+
+		// user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			$user_id = (int) $raw_properties['user_id'];
+			unset( $raw_properties['user_id'] );
+		}
+
+		$day_html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'id'   => bp_get_the_profile_field_input_name() . '_day',
+				'name' => bp_get_the_profile_field_input_name() . '_day',
+			),
+			$raw_properties
+		) );
+
+		$month_html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'id'   => bp_get_the_profile_field_input_name() . '_month',
+				'name' => bp_get_the_profile_field_input_name() . '_month',
+			),
+			$raw_properties
+		) );
+
+		$year_html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'id'   => bp_get_the_profile_field_input_name() . '_year',
+				'name' => bp_get_the_profile_field_input_name() . '_year',
+			),
+			$raw_properties
+		) );
+	?>
+		<div class="datebox">
+
+			<label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+
+			<select <?php echo $day_html; ?>>
+				<?php bp_the_profile_field_options( array( 'type' => 'day', 'user_id' => $user_id ) ); ?>
+			</select>
+
+			<select <?php echo $month_html; ?>>
+				<?php bp_the_profile_field_options( array( 'type' => 'month', 'user_id' => $user_id ) ); ?>
+			</select>
+
+			<select <?php echo $year_html; ?>>
+				<?php bp_the_profile_field_options( array( 'type' => 'year', 'user_id' => $user_id ) ); ?>
+			</select>
+
+		</div>
+	<?php
+	}
+
+	/**
+	 * Output the edit field options HTML for this field type.
+	 *
+	 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
+	 * These are stored separately in the database, and their templating is handled seperately.
+	 *
+	 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
+	 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_options_html( array $args = array() ) {
+		$options = $this->field_obj->get_children();
+		$date    = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] );
+
+		$day   = 0;
+		$month = 0;
+		$year  = 0;
+		$html  = '';
+
+		// Set day, month, year defaults
+		if ( ! empty( $date ) ) {
+
+			// If Unix timestamp
+			if ( is_numeric( $date ) ) {
+				$day   = date( 'j', $date );
+				$month = date( 'F', $date );
+				$year  = date( 'Y', $date );
+
+			// If MySQL timestamp
+			} else {
+				$day   = mysql2date( 'j', $date );
+				$month = mysql2date( 'F', $date, false ); // Not localized, so that selected() works below
+				$year  = mysql2date( 'Y', $date );
+			}
+		}
+
+		// Check for updated posted values, and errors preventing them from being saved first time.
+		if ( ! empty( $_POST['field_' . $this->field_obj->id . '_day'] ) ) {
+			$new_day = (int) $_POST['field_' . $this->field_obj->id . '_day'];
+			$day     = ( $day != $new_day ) ? $new_day : $day;
+		}
+
+		if ( ! empty( $_POST['field_' . $this->field_obj->id . '_month'] ) ) {
+			$new_month = (int) $_POST['field_' . $this->field_obj->id . '_month'];
+			$month     = ( $month != $new_month ) ? $new_month : $month;
+		}
+
+		if ( ! empty( $_POST['field_' . $this->field_obj->id . '_year'] ) ) {
+			$new_year = date( 'j', (int) $_POST['field_' . $this->field_obj->id . '_year'] );
+			$year     = ( $year != $new_year ) ? $new_year : $year;
+		}
+
+		// $type will be passed by calling function when needed
+		switch ( $args['type'] ) {
+			case 'day':
+				$html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $day, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) );
+
+				for ( $i = 1; $i < 32; ++$i ) {
+					$html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', (int) $i, selected( $day, $i, false ), (int) $i );
+				}
+			break;
+
+			case 'month':
+				$eng_months = array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' );
+
+				$months = array(
+					__( 'January', 'buddypress' ),
+					__( 'February', 'buddypress' ),
+					__( 'March', 'buddypress' ),
+					__( 'April', 'buddypress' ),
+					__( 'May', 'buddypress' ),
+					__( 'June', 'buddypress' ),
+					__( 'July', 'buddypress' ),
+					__( 'August', 'buddypress' ),
+					__( 'September', 'buddypress' ),
+					__( 'October', 'buddypress' ),
+					__( 'November', 'buddypress' ),
+					__( 'December', 'buddypress' )
+				);
+
+				$html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $month, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) );
+
+				for ( $i = 0; $i < 12; ++$i ) {
+					$html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $eng_months[$i] ), selected( $month, $eng_months[$i], false ), $months[$i] );
+				}
+			break;
+
+			case 'year':
+				$html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $year, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) );
+
+				for ( $i = 2037; $i > 1901; $i-- ) {
+					$html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', (int) $i, selected( $year, $i, false ), (int) $i );
+				}
+			break;
+		}
+
+		echo apply_filters( 'bp_get_the_profile_field_datebox', $html, $args['type'], $day, $month, $year, $this->field_obj->id, $date );
+	}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+		$day_html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'id'   => bp_get_the_profile_field_input_name() . '_day',
+				'name' => bp_get_the_profile_field_input_name() . '_day',
+			),
+			$raw_properties
+		) );
+
+		$month_html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'id'   => bp_get_the_profile_field_input_name() . '_month',
+				'name' => bp_get_the_profile_field_input_name() . '_month',
+			),
+			$raw_properties
+		) );
+
+		$year_html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'id'   => bp_get_the_profile_field_input_name() . '_year',
+				'name' => bp_get_the_profile_field_input_name() . '_year',
+			),
+			$raw_properties
+		) );
+	?>
+		<select <?php echo $day_html; ?>>
+			<?php bp_the_profile_field_options( 'type=day' ); ?>
+		</select>
+
+		<select <?php echo $month_html; ?>>
+			<?php bp_the_profile_field_options( 'type=month' ); ?>
+		</select>
+
+		<select <?php echo $year_html; ?>>
+			<?php bp_the_profile_field_options( 'type=year' ); ?>
+		</select>
+	<?php
+	}
+
+	/**
+	 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields
+	 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {}
+}
+
+/**
+ * Checkbox xprofile field type.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_Field_Type_Checkbox extends BP_XProfile_Field_Type {
+
+	/**
+	 * Constructor for the checkbox field type
+	 *
+	 * @since BuddyPress (2.0.0)
+ 	 */
+	public function __construct() {
+		parent::__construct();
+
+		$this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Checkboxes', 'xprofile field type', 'buddypress' );
+
+		$this->supports_multiple_defaults = true;
+		$this->accepts_null_value         = true;
+		$this->supports_options           = true;
+
+		$this->set_format( '/^.+$/', 'replace' );
+		do_action( 'bp_xprofile_field_type_checkbox', $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.checkbox.html permitted attributes} that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+		$user_id = bp_displayed_user_id();
+
+		// user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			$user_id = (int) $raw_properties['user_id'];
+			unset( $raw_properties['user_id'] );
+		}
+	?>
+		<div class="checkbox">
+
+			<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+			<?php bp_the_profile_field_options( "user_id={$user_id}" ); ?>
+
+		</div>
+		<?php
+	}
+
+	/**
+	 * Output the edit field options HTML for this field type.
+	 *
+	 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
+	 * These are stored separately in the database, and their templating is handled seperately.
+	 *
+	 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
+	 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_options_html( array $args = array() ) {
+		$options       = $this->field_obj->get_children();
+		$option_values = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] );
+		$option_values = (array) maybe_unserialize( $option_values );
+
+		$html = '';
+
+		// Check for updated posted values, but errors preventing them from being saved first time
+		if ( isset( $_POST['field_' . $this->field_obj->id] ) && $option_values != maybe_serialize( $_POST['field_' . $this->field_obj->id] ) ) {
+			if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) {
+				$option_values = array_map( 'sanitize_text_field', $_POST['field_' . $this->field_obj->id] );
+			}
+		}
+
+		for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
+			$selected = '';
+
+			// First, check to see whether the user's saved values match the option
+			for ( $j = 0, $count_values = count( $option_values ); $j < $count_values; ++$j ) {
+
+				// Run the allowed option name through the before_save filter, so we'll be sure to get a match
+				$allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
+
+				if ( $option_values[$j] === $allowed_options || in_array( $allowed_options, $option_values ) ) {
+					$selected = ' checked="checked"';
+					break;
+				}
+			}
+
+			// If the user has not yet supplied a value for this field, check to see whether there is a default value available
+			if ( ! is_array( $option_values ) && empty( $option_values ) && empty( $selected ) && ! empty( $options[$k]->is_default_option ) ) {
+				$selected = ' checked="checked"';
+			}
+
+			$new_html = sprintf( '<label><input %1$s type="checkbox" name="%2$s" id="%3$s" value="%4$s">%5$s</label>',
+				$selected,
+				esc_attr( "field_{$this->field_obj->id}[]" ),
+				esc_attr( "field_{$options[$k]->id}_{$k}" ),
+				esc_attr( stripslashes( $options[$k]->name ) ),
+				esc_html( stripslashes( $options[$k]->name ) )
+			);
+			$html .= apply_filters( 'bp_get_the_profile_field_options_checkbox', $new_html, $options[$k], $this->field_obj->id, $selected, $k );
+		}
+
+		echo $html;
+	}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+		bp_the_profile_field_options();
+	}
+
+	/**
+	 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
+		parent::admin_new_field_html( $current_field, 'checkbox' );
+	}
+}
+
+/**
+ * Radio button xprofile field type.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_Field_Type_Radiobutton extends BP_XProfile_Field_Type {
+
+	/**
+	 * Constructor for the radio button field type
+	 *
+	 * @since BuddyPress (2.0.0)
+ 	 */
+	public function __construct() {
+		parent::__construct();
+
+		$this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Radio Buttons', 'xprofile field type', 'buddypress' );
+
+		$this->supports_options = true;
+
+		$this->set_format( '/^.+$/', 'replace' );
+		do_action( 'bp_xprofile_field_type_radiobutton', $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.radio.html permitted attributes} that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+		$user_id = bp_displayed_user_id();
+
+		// user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			$user_id = (int) $raw_properties['user_id'];
+			unset( $raw_properties['user_id'] );
+		}
+	?>
+		<div class="radio">
+
+			<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+			<?php bp_the_profile_field_options( "user_id={$user_id}" );
+
+			if ( ! bp_get_the_profile_field_is_required() ) : ?>
+				<a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>' );"><?php esc_html_e( 'Clear', 'buddypress' ); ?></a>
+			<?php endif; ?>
+
+		</div>
+		<?php
+	}
+
+	/**
+	 * Output the edit field options HTML for this field type.
+	 *
+	 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
+	 * These are stored separately in the database, and their templating is handled seperately.
+	 *
+	 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
+	 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_options_html( array $args = array() ) {
+		$option_value = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] );
+		$options      = $this->field_obj->get_children();
+
+		$html = sprintf( '<div id="%s">', esc_attr( 'field_' . $this->field_obj->id ) );
+
+		for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
+
+			// Check for updated posted values, but errors preventing them from being saved first time
+			if ( isset( $_POST['field_' . $this->field_obj->id] ) && $option_value != $_POST['field_' . $this->field_obj->id] ) {
+				if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) {
+					$option_value = sanitize_text_field( $_POST['field_' . $this->field_obj->id] );
+				}
+			}
+
+			// Run the allowed option name through the before_save filter, so we'll be sure to get a match
+			$allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
+			$selected        = '';
+
+			if ( $option_value === $allowed_options || ( empty( $option_value ) && ! empty( $options[$k]->is_default_option ) ) ) {
+				$selected = ' checked="checked"';
+			}
+
+			$new_html = sprintf( '<label><input %1$s type="radio" name="%2$s" id="%3$s" value="%4$s">%5$s</label>',
+				$selected,
+				esc_attr( "field_{$this->field_obj->id}" ),
+				esc_attr( "option_{$options[$k]->id}" ),
+				esc_attr( stripslashes( $options[$k]->name ) ),
+				esc_html( stripslashes( $options[$k]->name ) )
+			);
+			$html .= apply_filters( 'bp_get_the_profile_field_options_radio', $new_html, $options[$k], $this->field_obj->id, $selected, $k );
+		}
+
+		echo $html . '</div>';
+	}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+		bp_the_profile_field_options();
+
+		if ( ! bp_get_the_profile_field_is_required() ) : ?>
+			<a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>' );"><?php esc_html_e( 'Clear', 'buddypress' ); ?></a>
+		<?php endif; ?>
+	<?php
+	}
+
+	/**
+	 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
+		parent::admin_new_field_html( $current_field, 'radio' );
+	}
+}
+
+/**
+ * Multi-selectbox xprofile field type.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_Field_Type_Multiselectbox extends BP_XProfile_Field_Type {
+
+	/**
+	 * Constructor for the multi-selectbox field type
+	 *
+	 * @since BuddyPress (2.0.0)
+ 	 */
+	public function __construct() {
+		parent::__construct();
+
+		$this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Multi Select Box', 'xprofile field type', 'buddypress' );
+
+		$this->supports_multiple_defaults = true;
+		$this->accepts_null_value         = true;
+		$this->supports_options           = true;
+
+		$this->set_format( '/^.+$/', 'replace' );
+		do_action( 'bp_xprofile_field_type_multiselectbox', $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/select.html permitted attributes} that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+		$user_id = bp_displayed_user_id();
+
+		// user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			$user_id = (int) $raw_properties['user_id'];
+			unset( $raw_properties['user_id'] );
+		}
+
+		$html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'multiple' => 'multiple',
+				'id'       => bp_get_the_profile_field_input_name() . '[]',
+				'name'     => bp_get_the_profile_field_input_name() . '[]',
+			),
+			$raw_properties
+		) );
+	?>
+		<label for="<?php bp_the_profile_field_input_name(); ?>[]"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+		<select <?php echo $html; ?>>
+			<?php bp_the_profile_field_options( "user_id={$user_id}" ); ?>
+		</select>
+
+		<?php if ( ! bp_get_the_profile_field_is_required() ) : ?>
+			<a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>[]' );"><?php esc_html_e( 'Clear', 'buddypress' ); ?></a>
+		<?php endif; ?>
+	<?php
+	}
+
+	/**
+	 * Output the edit field options HTML for this field type.
+	 *
+	 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
+	 * These are stored separately in the database, and their templating is handled seperately.
+	 *
+	 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
+	 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_options_html( array $args = array() ) {
+		$original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) );
+
+		$options = $this->field_obj->get_children();
+		$html    = '';
+
+		if ( empty( $original_option_values ) && ! empty( $_POST['field_' . $this->field_obj->id] ) ) {
+			$original_option_values = sanitize_text_field( $_POST['field_' . $this->field_obj->id] );
+		}
+
+		$option_values = (array) $original_option_values;
+		for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
+			$selected = '';
+
+			// Check for updated posted values, but errors preventing them from being saved first time
+			foreach( $option_values as $i => $option_value ) {
+				if ( isset( $_POST['field_' . $this->field_obj->id] ) && $_POST['field_' . $this->field_obj->id][$i] != $option_value ) {
+					if ( ! empty( $_POST['field_' . $this->field_obj->id][$i] ) ) {
+						$option_values[] = sanitize_text_field( $_POST['field_' . $this->field_obj->id][$i] );
+					}
+				}
+			}
+
+			// Run the allowed option name through the before_save filter, so we'll be sure to get a match
+			$allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
+
+			// First, check to see whether the user-entered value matches
+			if ( in_array( $allowed_options, $option_values ) ) {
+				$selected = ' selected="selected"';
+			}
+
+			// Then, if the user has not provided a value, check for defaults
+			if ( ! is_array( $original_option_values ) && empty( $option_values ) && ! empty( $options[$k]->is_default_option ) ) {
+				$selected = ' selected="selected"';
+			}
+
+			$html .= apply_filters( 'bp_get_the_profile_field_options_multiselect', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_html( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $this->field_obj->id, $selected, $k );
+		}
+
+		echo $html;
+	}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+		$html = $this->get_edit_field_html_elements( array_merge(
+			array( 'multiple' => 'multiple' ),
+			$raw_properties
+		) );
+	?>
+		<select <?php echo $html; ?>>
+			<?php bp_the_profile_field_options(); ?>
+		</select>
+	<?php
+	}
+
+	/**
+	 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
+		parent::admin_new_field_html( $current_field, 'checkbox' );
+	}
+}
+
+/**
+ * Selectbox xprofile field type.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_Field_Type_Selectbox extends BP_XProfile_Field_Type {
+
+	/**
+	 * Constructor for the selectbox field type
+	 *
+	 * @since BuddyPress (2.0.0)
+ 	 */
+	public function __construct() {
+		parent::__construct();
+
+		$this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Drop Down Select Box', 'xprofile field type', 'buddypress' );
+
+		$this->supports_options = true;
+
+		$this->set_format( '/^.+$/', 'replace' );
+		do_action( 'bp_xprofile_field_type_selectbox', $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/select.html permitted attributes} that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+		$user_id = bp_displayed_user_id();
+
+		// user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			$user_id = (int) $raw_properties['user_id'];
+			unset( $raw_properties['user_id'] );
+		}
+
+		$html = $this->get_edit_field_html_elements( $raw_properties );
+	?>
+		<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+		<select <?php echo $html; ?>>
+			<?php bp_the_profile_field_options( "user_id={$user_id}" ); ?>
+		</select>
+	<?php
+	}
+
+	/**
+	 * Output the edit field options HTML for this field type.
+	 *
+	 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
+	 * These are stored separately in the database, and their templating is handled seperately.
+	 *
+	 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
+	 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_options_html( array $args = array() ) {
+		$original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) );
+
+		$options = $this->field_obj->get_children();
+		$html     = '<option value="">' . /* translators: no option picked in select box */ esc_html__( '----', 'buddypress' ) . '</option>';
+
+		if ( empty( $original_option_values ) && !empty( $_POST['field_' . $this->field_obj->id] ) ) {
+			$original_option_values = sanitize_text_field(  $_POST['field_' . $this->field_obj->id] );
+		}
+
+		$option_values = (array) $original_option_values;
+		for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
+			$selected = '';
+
+			// Check for updated posted values, but errors preventing them from being saved first time
+			foreach( $option_values as $i => $option_value ) {
+				if ( isset( $_POST['field_' . $this->field_obj->id] ) && $_POST['field_' . $this->field_obj->id] != $option_value ) {
+					if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) {
+						$option_values[$i] = sanitize_text_field( $_POST['field_' . $this->field_obj->id] );
+					}
+				}
+			}
+
+			// Run the allowed option name through the before_save filter, so we'll be sure to get a match
+			$allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
+
+			// First, check to see whether the user-entered value matches
+			if ( in_array( $allowed_options, $option_values ) ) {
+				$selected = ' selected="selected"';
+			}
+
+			// Then, if the user has not provided a value, check for defaults
+			if ( ! is_array( $original_option_values ) && empty( $option_values ) && $options[$k]->is_default_option ) {
+				$selected = ' selected="selected"';
+			}
+
+			$html .= apply_filters( 'bp_get_the_profile_field_options_select', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_html( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $this->field_obj->id, $selected, $k );
+		}
+
+		echo $html;
+	}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+		$html = $this->get_edit_field_html_elements( $raw_properties );
+	?>
+		<select <?php echo $html; ?>>
+			<?php bp_the_profile_field_options(); ?>
+		</select>
+	<?php
+	}
+
+	/**
+	 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
+		parent::admin_new_field_html( $current_field, 'radio' );
+	}
+}
+
+/**
+ * Textarea xprofile field type.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_Field_Type_Textarea extends BP_XProfile_Field_Type {
+
+	/**
+	 * Constructor for the textarea field type
+	 *
+	 * @since BuddyPress (2.0.0)
+ 	 */
+	public function __construct() {
+		parent::__construct();
+
+		$this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Multi-line Text Area', 'xprofile field type', 'buddypress' );
+
+		$this->set_format( '/^.*$/m', 'replace' );
+		do_action( 'bp_xprofile_field_type_textarea', $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/textarea.html permitted attributes} that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+
+		// user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			unset( $raw_properties['user_id'] );
+		}
+
+		$html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'cols' => 40,
+				'rows' => 5,
+			),
+			$raw_properties
+		) );
+	?>
+		<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+		<textarea <?php echo $html; ?>><?php bp_the_profile_field_edit_value(); ?></textarea>
+	<?php
+	}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+		$html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'cols' => 40,
+				'rows' => 5,
+			),
+			$raw_properties
+		) );
+	?>
+		<textarea <?php echo $html; ?>></textarea>
+	<?php
+	}
+
+	/**
+	 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields
+	 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {}
+}
+
+/**
+ * Textbox xprofile field type.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_Field_Type_Textbox extends BP_XProfile_Field_Type {
+
+	/**
+	 * Constructor for the textbox field type
+	 *
+	 * @since BuddyPress (2.0.0)
+ 	 */
+	public function __construct() {
+		parent::__construct();
+
+		$this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Text Box', 'xprofile field type', 'buddypress' );
+
+		$this->set_format( '/^.*$/', 'replace' );
+		do_action( 'bp_xprofile_field_type_textbox', $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.text.html permitted attributes} that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+
+		// user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			unset( $raw_properties['user_id'] );
+		}
+
+		$html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'type'  => 'text',
+				'value' => bp_get_the_profile_field_edit_value(),
+			),
+			$raw_properties
+		) );
+	?>
+		<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+		<input <?php echo $html; ?>>
+	<?php
+	}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+		$html = $this->get_edit_field_html_elements( array_merge(
+			array( 'type' => 'text' ),
+			$raw_properties
+		) );
+	?>
+		<input <?php echo $html; ?>>
+	<?php
+	}
+
+	/**
+	 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields
+	 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {}
+}
+
+/**
+ * Number xprofile field type.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+class BP_XProfile_Field_Type_Number extends BP_XProfile_Field_Type {
+
+	/**
+	 * Constructor for the number field type
+	 *
+	 * @since BuddyPress (2.0.0)
+ 	 */
+	public function __construct() {
+		parent::__construct();
+
+		$this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
+		$this->name     = _x( 'Number', 'xprofile field type', 'buddypress' );
+
+		$this->set_format( '/^\d+|-\d+$/', 'replace' );
+		do_action( 'bp_xprofile_field_type_number', $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.number.html permitted attributes} that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_html( array $raw_properties = array() ) {
+
+		// user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}.
+		if ( isset( $raw_properties['user_id'] ) ) {
+			unset( $raw_properties['user_id'] );
+		}
+
+		$html = $this->get_edit_field_html_elements( array_merge(
+			array(
+				'type'  => 'number',
+				'value' =>  bp_get_the_profile_field_edit_value(),
+			),
+			$raw_properties
+		) );
+	?>
+		<label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
+		<input <?php echo $html; ?>>
+	<?php
+	}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_field_html( array $raw_properties = array() ) {
+		$html = $this->get_edit_field_html_elements( array_merge(
+			array( 'type' => 'number' ),
+			$raw_properties
+		) );
+	?>
+		<input <?php echo $html; ?>>
+	<?php
+	}
+
+	/**
+	 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields
+	 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {}
+}
+
+/**
+ * Represents a type of XProfile field and holds meta information about the type of value that it accepts.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+abstract class BP_XProfile_Field_Type {
+
+	/**
+	 * @since BuddyPress (2.0.0)
+	 * @var array Field type validation regexes
+	 */
+	protected $validation_regex = array();
+
+	/**
+	 * @since BuddyPress (2.0.0)
+	 * @var array Field type whitelisted values
+	 */
+	protected $validation_whitelist = array();
+
+	/**
+	 * @since BuddyPress (2.0.0)
+	 * @var string The name of this field type
+	 */
+	public $name = '';
+
+	/**
+	 * The name of the category that this field type should be grouped with. Used on the [Users > Profile Fields] screen in wp-admin.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 * @var string
+	 */
+	public $category = '';
+
+	/**
+	 * @since BuddyPress (2.0.0)
+	 * @var bool If this is set, allow BP to store null/empty values for this field type.
+	 */
+	public $accepts_null_value = false;
+
+	/**
+	 * If this is set, BP will set this field type's validation whitelist from the field's options (e.g checkbox, selectbox).
+	 *
+	 * @since BuddyPress (2.0.0)
+	 * @var bool Does this field support options? e.g. selectbox, radio buttons, etc.
+	 */
+	public $supports_options = false;
+
+	/**
+	 * @since BuddyPress (2.0.0)
+	 * @var bool Does this field type support multiple options being set as default values? e.g. multiselectbox, checkbox.
+	 */
+	public $supports_multiple_defaults = false;
+
+	/**
+	 * @since BuddyPress (2.0.0)
+	 * @var BP_XProfile_Field If this object is created by instantiating a {@link BP_XProfile_Field}, this is a reference back to that object.
+	 */
+	public $field_obj = null;
+
+	/**
+	 * Constructor
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function __construct() {
+		do_action( 'bp_xprofile_field_type', $this );
+	}
+
+	/**
+	 * Set a regex that profile data will be asserted against.
+	 * 
+	 * You can call this method multiple times to set multiple formats. When validation is performed,
+	 * it's successful as long as the new value matches any one of the registered formats.
+	 * 
+	 * @param string $format Regex string
+	 * @param string $replace_format Optional; if 'replace', replaces the format instead of adding to it. Defaults to 'add'.
+	 * @return BP_XProfile_Field_Type
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function set_format( $format, $replace_format = 'add' ) {
+
+		$format = apply_filters( 'bp_xprofile_field_type_set_format', $format, $replace_format, $this );
+
+		if ( 'add' === $replace_format ) {
+			$this->validation_regex[] = $format;
+		} elseif ( 'replace' === $replace_format ) {
+			$this->validation_regex = array( $format );
+		}
+
+		return $this;
+	}
+
+	/**
+	 * Add a value to this type's whitelist that that profile data will be asserted against.
+	 * 
+	 * You can call this method multiple times to set multiple formats. When validation is performed,
+	 * it's successful as long as the new value matches any one of the registered formats.
+	 * 
+	 * @param string|array $values
+	 * @return BP_XProfile_Field_Type
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function set_whitelist_values( $values ) {
+		foreach ( (array) $values as $value ) {
+			$this->validation_whitelist[] = apply_filters( 'bp_xprofile_field_type_set_whitelist_values', $value, $values, $this );
+		}
+
+		return $this;
+	}
+
+	/**
+	 * Check the given string against the registered formats for this field type.
+	 *
+	 * This method doesn't support chaining.
+	 *
+	 * @param string|array $values Value to check against the registered formats
+	 * @return bool True if the value validates
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function is_valid( $values ) {
+		$validated = false;
+
+		// Some types of field (e.g. multi-selectbox) may have multiple values to check
+		foreach ( (array) $values as $value ) {
+
+			// Validate the $value against the type's accepted format(s).
+			foreach ( $this->validation_regex as $format ) {
+				if ( 1 === preg_match( $format, $value ) ) {
+					$validated = true;
+					continue;
+
+				} else {
+					$validated = false;
+				}
+			}
+		}
+
+		// Handle field types with accepts_null_value set if $values is an empty array
+		if ( ! $validated && is_array( $values ) && empty( $values ) && $this->accepts_null_value ) {
+			$validated = true;
+		}
+
+		// If there's a whitelist set, also check the $value.
+		if ( $validated && ! empty( $values ) && ! empty( $this->validation_whitelist ) ) {
+
+			foreach ( (array) $values as $value ) {
+				$validated = in_array( $value, $this->validation_whitelist, true );
+			}
+		}
+
+		return (bool) apply_filters( 'bp_xprofile_field_type_is_valid', $validated, $values, $this );
+	}
+
+	/**
+	 * Output the edit field HTML for this field type.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	abstract public function edit_field_html( array $raw_properties = array() );
+
+	/**
+	 * Output the edit field options HTML for this field type.
+	 *
+	 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
+	 * These are stored separately in the database, and their templating is handled separately.
+	 * Populate this method in a child class if it's required. Otherwise, you can leave it out.
+	 *
+	 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
+	 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function edit_field_options_html( array $args = array() ) {}
+
+	/**
+	 * Output HTML for this field type on the wp-admin Profile Fields screen.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
+	 * @since BuddyPress (2.0.0)
+	 */
+	abstract public function admin_field_html( array $raw_properties = array() );
+
+	/**
+	 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
+	 *
+	 * You don't need to implement this method for all field types. It's used in core by the
+	 * selectbox, multi selectbox, checkbox, and radio button fields, to allow the admin to
+	 * enter the child option values (e.g. the choices in a select box).
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 *
+	 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
+	 * @param string $control_type Optional. HTML input type used to render the current field's child options.
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
+		$type = array_search( get_class( $this ), bp_xprofile_get_field_types() );
+		if ( false === $type ) {
+			return;
+		}
+
+		$class            = $current_field->type != $type ? 'display: none;' : '';
+		$current_type_obj = bp_xprofile_create_field_type( $type );
+		?>
+
+		<div id="<?php echo esc_attr( $type ); ?>" class="postbox bp-options-box" style="<?php echo esc_attr( $class ); ?> margin-top: 15px;">
+			<h3><?php esc_html_e( 'Please enter options for this Field:', 'buddypress' ); ?></h3>
+			<div class="inside">
+				<p>
+					<label for="sort_order_<?php echo esc_attr( $type ); ?>"><?php esc_html_e( 'Sort Order:', 'buddypress' ); ?></label>
+					<select name="sort_order_<?php echo esc_attr( $type ); ?>" id="sort_order_<?php echo esc_attr( $type ); ?>" >
+						<option value="custom" <?php selected( 'custom', $current_field->order_by ); ?>><?php esc_html_e( 'Custom',     'buddypress' ); ?></option>
+						<option value="asc"    <?php selected( 'asc',    $current_field->order_by ); ?>><?php esc_html_e( 'Ascending',  'buddypress' ); ?></option>
+						<option value="desc"   <?php selected( 'desc',   $current_field->order_by ); ?>><?php esc_html_e( 'Descending', 'buddypress' ); ?></option>
+					</select>
+				</p>
+
+				<?php
+				$options = $current_field->get_children( true );
+
+				// If no children options exists for this field, check in $_POST for a submitted form (e.g. on the "new field" screen).
+				if ( ! $options ) {
+
+					$options = array();
+					$i       = 1;
+
+					while ( isset( $_POST[$type . '_option'][$i] ) ) {
+
+						// Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE.
+						if ( $current_type_obj->supports_options && ! $current_type_obj->supports_multiple_defaults && isset( $_POST["isDefault_{$type}_option"][$i] ) && (int) $_POST["isDefault_{$type}_option"] === $i ) {
+							$is_default_option = true;
+						} elseif ( isset( $_POST["isDefault_{$type}_option"][$i] ) ) {
+							$is_default_option = (bool) $_POST["isDefault_{$type}_option"][$i];
+						} else {
+							$is_default_option = false;
+						}
+
+						// Grab the values from $_POST to use as the form's options
+						$options[] = (object) array(
+							'id'                => -1,
+							'is_default_option' => $is_default_option,
+							'name'              => sanitize_text_field( stripslashes( $_POST[$type . '_option'][$i] ) ),
+						);
+
+						++$i;
+					}
+
+					// If there are still no children options set, this must be the "new field" screen, so add one new/empty option.
+					if ( ! $options ) {
+						$options[] = (object) array(
+							'id'                => -1,
+							'is_default_option' => false,
+							'name'              => '',
+						);
+					}
+				}
+
+				// Render the markup for the children options
+				if ( ! empty( $options ) ) {
+					$default_name = '';
+
+					for ( $i = 0, $count = count( $options ); $i < $count; ++$i ) :
+						$j = $i + 1;
+
+						// Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE.
+						if ( $current_type_obj->supports_options && $current_type_obj->supports_multiple_defaults ) {
+							$default_name = '[' . $j . ']';
+						}
+						?>
+
+						<p class="sortable">
+							<span>&nbsp;&Xi;&nbsp;</span>
+							<input type="text" name="<?php echo esc_attr( "{$type}_option[{$j}]" ); ?>" id="<?php echo esc_attr( "{$type}_option{$j}" ); ?>" value="<?php echo esc_attr( $options[$i]->name ); ?>" />
+							<input type="<?php echo esc_attr( $control_type ); ?>" name="<?php echo esc_attr( "isDefault_{$type}_option{$default_name}" ); ?>" <?php checked( $options[$i]->is_default_option, true ); ?> value="<?php echo esc_attr( $j ); ?>" />
+							<span><?php _e( 'Default Value', 'buddypress' ); ?></span>
+						</p>
+					<?php endfor; ?>
+
+					<input type="hidden" name="<?php echo esc_attr( "{$type}_option_number" ); ?>" id="<?php echo esc_attr( "{$type}_option_number" ); ?>" value="<?php echo esc_attr( $j + 1 ); ?>" />
+				<?php } ?>
+
+				<div id="<?php echo esc_attr( "{$type}_more" ); ?>"></div>
+				<p><a href="javascript:add_option('<?php echo esc_js( $type ); ?>')"><?php esc_html_e( 'Add Another Option', 'buddypress' ); ?></a></p>
+			</div>
+		</div>
+
+		<?php
+	}
+
+
+	/**
+	 * Internal protected/private helper methods past this point.
+	 */
+
+	/**
+	 * Get a sanitised and escaped string of the edit field's HTML elements and attributes.
+	 *
+	 * Must be used inside the {@link bp_profile_fields()} template loop.
+	 * This method was intended to be static but couldn't be because php.net/lsb/ requires PHP >= 5.3.
+	 *
+	 * @param array $properties Optional key/value array of attributes for this edit field.
+	 * @return string
+	 * @since BuddyPress (2.0.0)
+	 */
+	protected function get_edit_field_html_elements( array $properties = array() ) {
+
+		$properties = array_merge( array(
+			'id'   => bp_get_the_profile_field_input_name(),
+			'name' => bp_get_the_profile_field_input_name(),
+		), $properties );
+
+		if ( bp_get_the_profile_field_is_required() ) {
+			$properties['aria-required'] = 'true';
+		}
+
+		$html       = '';
+		$properties = (array) apply_filters( 'bp_xprofile_field_edit_html_elements', $properties, get_class( $this ) );
+
+		foreach ( $properties as $name => $value ) {
+			$html .= sprintf( '%s="%s" ', sanitize_key( $name ), esc_attr( $value ) );
+		}
+
+		return $html;
+	}
+}
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-cssjs.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-cssjs.php
index 1c8c43226f0b81a522065b6ef26787ef7546c9e9..8fb4f671108bf593973c287eabd9b11673dadc1d 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-cssjs.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-cssjs.php
@@ -18,7 +18,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
 function xprofile_add_admin_css() {
 	if ( !empty( $_GET['page'] ) && strpos( $_GET['page'], 'bp-profile-setup' ) !== false ) {
 		$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
-		wp_enqueue_style( 'xprofile-admin-css', BP_PLUGIN_URL . "bp-xprofile/admin/css/admin{$min}.css", array(), bp_get_version() );
+		wp_enqueue_style( 'xprofile-admin-css', buddypress()->plugin_url . "bp-xprofile/admin/css/admin{$min}.css", array(), bp_get_version() );
 	}
 }
 add_action( 'admin_enqueue_scripts', 'xprofile_add_admin_css' );
@@ -38,7 +38,7 @@ function xprofile_add_admin_js() {
 		wp_enqueue_script( 'jquery-ui-sortable'  );
 
 		$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
-		wp_enqueue_script( 'xprofile-admin-js', BP_PLUGIN_URL . "bp-xprofile/admin/js/admin{$min}.js", array( 'jquery', 'jquery-ui-sortable' ), bp_get_version() );
+		wp_enqueue_script( 'xprofile-admin-js', buddypress()->plugin_url . "bp-xprofile/admin/js/admin{$min}.js", array( 'jquery', 'jquery-ui-sortable' ), bp_get_version() );
 	}
 }
 add_action( 'admin_enqueue_scripts', 'xprofile_add_admin_js', 1 );
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-filters.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-filters.php
index bde9c50cc77329718c2930663b6a87eee9d2e3a9..c0491948bdb827dd1aca73e339a7b88abf623c0b 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-filters.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-filters.php
@@ -73,8 +73,6 @@ function xprofile_filter_kses( $content ) {
 }
 
 /**
- * xprofile_sanitize_data_value_before_save ( $field_value, $field_id )
- *
  * Safely runs profile field data through kses and force_balance_tags.
  *
  * @param string $field_value
@@ -85,8 +83,9 @@ function xprofile_filter_kses( $content ) {
 function xprofile_sanitize_data_value_before_save ( $field_value, $field_id, $reserialize = true ) {
 
 	// Return if empty
-	if ( empty( $field_value ) )
-		return;
+	if ( empty( $field_value ) ) {
+		return $field_value;
+	}
 
 	// Value might be serialized
 	$field_value = maybe_unserialize( $field_value );
@@ -215,9 +214,9 @@ function xprofile_filter_comments( $comments, $post_id ) {
 	}
 
 	// Pull up the xprofile fullname of each commenter
-	if ( $fullnames = BP_XProfile_ProfileData::get_value_byid( 1, $user_ids ) ) {
-		foreach( (array) $fullnames as $user ) {
-			$users[ $user->user_id ] = trim( stripslashes( $user->value ) );
+	if ( $fullnames = bp_core_get_user_displaynames( $user_ids ) ) {
+		foreach( (array) $fullnames as $user_id => $user_fullname ) {
+			$users[ $user_id ] = trim( stripslashes( $user_fullname ) );
 		}
 	}
 
@@ -247,16 +246,113 @@ add_filter( 'comments_array', 'xprofile_filter_comments', 10, 2 );
 function bp_xprofile_filter_user_query_populate_extras( BP_User_Query $user_query, $user_ids_sql ) {
 	global $bp, $wpdb;
 
-	if ( bp_is_active( 'xprofile' ) ) {
-		$fullname_field_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", bp_xprofile_fullname_field_name() ) );
-		$user_id_names     = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, value as fullname FROM {$bp->profile->table_name_data} WHERE user_id IN ({$user_ids_sql}) AND field_id = %d", $fullname_field_id ) );
+	if ( ! bp_is_active( 'xprofile' ) ) {
+		return;
+	}
 
-		// Loop through names and override each user's fullname
-		foreach ( $user_id_names as $user ) {
-			if ( isset( $user_query->results[ $user->user_id ] ) ) {
-				$user_query->results[ $user->user_id ]->fullname = $user->fullname;
-			}
+	$user_id_names = bp_core_get_user_displaynames( $user_query->user_ids );
+
+	// Loop through names and override each user's fullname
+	foreach ( $user_id_names as $user_id => $user_fullname ) {
+		if ( isset( $user_query->results[ $user_id ] ) ) {
+			$user_query->results[ $user_id ]->fullname = $user_fullname;
 		}
 	}
 }
 add_filter( 'bp_user_query_populate_extras', 'bp_xprofile_filter_user_query_populate_extras', 2, 2 );
+
+/**
+ * Filter meta queries to modify for the xprofile data schema.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @access private Do not use.
+ *
+ * @param string $q SQL query.
+ * @return string
+ */
+function bp_xprofile_filter_meta_query( $q ) {
+	global $wpdb;
+
+	// Get the first word of the command
+	preg_match( '/^(\S+)/', $q, $first_word_matches );
+
+	if ( empty( $first_word_matches[0] ) ) {
+		return $q;
+	}
+
+	// Get the field type
+	preg_match( '/xprofile_(group|field|data)_id/', $q, $matches );
+
+	if ( empty( $matches[0] ) || empty( $matches[1] ) ) {
+		return $q;
+	}
+
+	switch ( $first_word_matches[0] ) {
+
+		/**
+		 * SELECT:
+		 * - replace 'xprofile_{fieldtype}_id' with 'object_id'
+		 * - ensure that 'object_id' is aliased to 'xprofile_{fieldtype}_id',
+		 *   because update_meta_cache() needs the column name to parse
+		 *   the query results
+		 * - append the 'object type' WHERE clause
+		 */
+		case 'SELECT' :
+			$q = str_replace(
+				array(
+					$matches[0],
+					'SELECT object_id',
+					'WHERE ',
+				),
+				array(
+					'object_id',
+					'SELECT object_id AS ' . $matches[0],
+					$wpdb->prepare( 'WHERE object_type = %s AND ', $matches[1] ),
+				),
+				$q
+			);
+			break;
+
+		/**
+		 * UPDATE and DELETE:
+		 * - replace 'xprofile_{fieldtype}_id' with 'object_id'
+		 * - append the 'object type' WHERE clause
+		 */
+		case 'UPDATE' :
+		case 'DELETE' :
+			$q = str_replace(
+				array(
+					$matches[0],
+					'WHERE ',
+				),
+				array(
+					'object_id',
+					$wpdb->prepare( 'WHERE object_type = %s AND ', $matches[1] ),
+				),
+				$q
+			);
+			break;
+
+		/**
+		 * UPDATE and DELETE:
+		 * - replace 'xprofile_{fieldtype}_id' with 'object_id'
+		 * - ensure that the object_type field gets filled in
+		 */
+		case 'INSERT' :
+			$q = str_replace(
+				array(
+					'`' . $matches[0] . '`',
+					'VALUES (',
+				),
+				array(
+					'`object_type`,`object_id`',
+					$wpdb->prepare( "VALUES (%s,", $matches[1] ),
+				),
+				$q
+			);
+			break;
+	}
+
+	return $q;
+}
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-functions.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-functions.php
index 03a88f8c7f9c2a7f33eb16416c210dbc93e7b5f6..31f890a93d74f46466dcf37fa4e720ce2fc1fe8e 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-functions.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-functions.php
@@ -60,6 +60,51 @@ function xprofile_update_field_group_position( $field_group_id, $position ) {
 
 /*** Field Management *********************************************************/
 
+/**
+ * Get details of all xprofile field types.
+ *
+ * @return array Key/value pairs (field type => class name).
+ * @since BuddyPress (2.0.0)
+ */
+function bp_xprofile_get_field_types() {
+	$fields = array(
+		'checkbox'       => 'BP_XProfile_Field_Type_Checkbox',
+		'datebox'        => 'BP_XProfile_Field_Type_Datebox',
+		'multiselectbox' => 'BP_XProfile_Field_Type_Multiselectbox',
+		'number'         => 'BP_XProfile_Field_Type_Number',
+		'radio'          => 'BP_XProfile_Field_Type_Radiobutton',
+		'selectbox'      => 'BP_XProfile_Field_Type_Selectbox',
+		'textarea'       => 'BP_XProfile_Field_Type_Textarea',
+		'textbox'        => 'BP_XProfile_Field_Type_Textbox',
+	);
+
+	// If you've added a custom field type in a plugin, register it with this filter.
+	return apply_filters( 'bp_xprofile_get_field_types', $fields );
+}
+
+/**
+ * Creates the specified field type object; used for validation and templating.
+ *
+ * @param string $type Type of profile field to create. See {@link bp_xprofile_get_field_types()} for default core values.
+ * @return object If field type unknown, returns BP_XProfile_Field_Type_Textarea. Otherwise returns an instance of the relevant child class of BP_XProfile_Field_Type.
+ * @since BuddyPress (2.0.0)
+ */
+function bp_xprofile_create_field_type( $type ) {
+
+	$field = bp_xprofile_get_field_types();
+	$class = isset( $field[$type] ) ? $field[$type] : '';
+
+	/**
+	 * For backpat and to handle (missing) field types introduced by other plugins, fallback to
+	 * textbox if a type is unknown. Textbox validation and display is intentionally low key.
+	 */
+	if ( $class && class_exists( $class ) ) {
+		return new $class;
+	} else {
+		return new BP_XProfile_Field_Type_Textbox;
+	}
+}
+
 function xprofile_insert_field( $args = '' ) {
 	global $bp;
 
@@ -211,41 +256,39 @@ function xprofile_set_field_data( $field, $user_id, $value, $is_required = false
 	if ( empty( $field_id ) )
 		return false;
 
-	if ( $is_required && ( empty( $value ) || !is_array( $value ) && !strlen( trim( $value ) ) ) )
+	// Special-case support for integer 0 for the number field type
+	if ( $is_required && ! is_integer( $value ) && $value !== '0' && ( empty( $value ) || ! is_array( $value ) && ! strlen( trim( $value ) ) ) ) {
 		return false;
+	}
 
-	$field = new BP_XProfile_Field( $field_id );
+	$field          = new BP_XProfile_Field( $field_id );
+	$field_type     = BP_XProfile_Field::get_type( $field_id );
+	$field_type_obj = bp_xprofile_create_field_type( $field_type );
+
+	/**
+	 * Certain types of fields (checkboxes, multiselects) may come through empty.
+	 * Save as empty array so this isn't overwritten by the default on next edit.
+	 *
+	 * Special-case support for integer 0 for the number field type
+	 */
+	if ( empty( $value ) && ! is_integer( $value ) && $value !== '0' && $field_type_obj->accepts_null_value ) {
+		$value = array();
+	}
 
-	// If the value is empty, then delete any field data that exists, unless the field is of a
-	// type where null values are semantically meaningful
-	if ( empty( $value ) && 'checkbox' != $field->type && 'multiselectbox' != $field->type ) {
+	// If the value is empty, then delete any field data that exists, unless the field is of a type where null values are semantically meaningful
+	if ( empty( $value ) && ! is_integer( $value ) && $value !== '0' && ! $field_type_obj->accepts_null_value ) {
 		xprofile_delete_field_data( $field_id, $user_id );
 		return true;
 	}
 
-	$possible_values = array();
-
-	// Check the value is an acceptable value
-	if ( 'checkbox' == $field->type || 'radio' == $field->type || 'selectbox' == $field->type || 'multiselectbox' == $field->type ) {
-		$options = $field->get_children();
-
-		foreach( $options as $option )
-			$possible_values[] = $option->name;
-
-		if ( is_array( $value ) ) {
-			foreach( $value as $i => $single ) {
-				if ( !in_array( $single, $possible_values ) ) {
-					unset( $value[$i] );
-				}
-			}
+	// For certain fields, only certain parameters are acceptable, so add them to the whitelist.
+	if ( $field_type_obj->supports_options ) {
+		$field_type_obj->set_whitelist_values( wp_list_pluck( $field->get_children(), 'name' ) );
+	}
 
-			// Reset the keys by merging with an empty array
-			$value = array_merge( array(), $value );
-		} else {
-			if ( !in_array( $value, $possible_values ) ) {
-				return false;
-			}
-		}
+	// Check the value is in an accepted format for this form field.
+	if ( ! $field_type_obj->is_valid( $value ) ) {
+		return false;
 	}
 
 	$field           = new BP_XProfile_ProfileData();
@@ -287,6 +330,40 @@ function xprofile_set_field_visibility_level( $field_id = 0, $user_id = 0, $visi
 	return bp_update_user_meta( $user_id, 'bp_xprofile_visibility_levels', $current_visibility_levels );
 }
 
+/**
+ * Get the visibility level for a field.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $field_id The ID of the xprofile field.
+ * @param int $user_id The ID of the user to whom the data belongs.
+ * @return string
+ */
+function xprofile_get_field_visibility_level( $field_id = 0, $user_id = 0 ) {
+	$current_level = '';
+
+	if ( empty( $field_id ) || empty( $user_id ) ) {
+		return $current_level;
+	}
+
+	$current_levels = bp_get_user_meta( $user_id, 'bp_xprofile_visibility_levels', true );
+	$current_level  = isset( $current_levels[ $field_id ] ) ? $current_levels[ $field_id ] : '';
+
+	// Use the user's stored level, unless custom visibility is disabled
+	$field = new BP_XProfile_Field( $field_id );
+	if ( isset( $field->allow_custom_visibility ) && 'disabled' === $field->allow_custom_visibility ) {
+		$current_level = $field->default_visibility;
+	}
+
+	// If we're still empty, it means that overrides are permitted, but the
+	// user has not provided a value. Use the default value.
+	if ( empty( $current_level ) ) {
+		$current_level = $field->default_visibility;
+	}
+
+	return $current_level;
+}
+
 function xprofile_delete_field_data( $field, $user_id ) {
 	if ( is_numeric( $field ) )
 		$field_id = $field;
@@ -419,6 +496,37 @@ function xprofile_avatar_upload_dir( $directory = false, $user_id = 0 ) {
 	) );
 }
 
+/**
+ * When search_terms are passed to BP_User_Query, search against xprofile fields.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $sql Clauses in the user_id SQL query.
+ * @param BP_User_Query User query object.
+ */
+function bp_xprofile_bp_user_query_search( $sql, BP_User_Query $query ) {
+	global $wpdb;
+
+	if ( empty( $query->query_vars['search_terms'] ) || empty( $sql['where']['search'] ) ) {
+		return $sql;
+	}
+
+	$bp = buddypress();
+
+	$search_terms_clean = esc_sql( esc_sql( $query->query_vars['search_terms'] ) );
+
+	// Combine the core search (against wp_users) into a single OR clause
+	// with the xprofile_data search
+	$search_core     = $sql['where']['search'];
+	$search_xprofile = "u.{$query->uid_name} IN ( SELECT user_id FROM {$bp->profile->table_name_data} WHERE value LIKE '%{$search_terms_clean}%' )";
+	$search_combined = "( {$search_xprofile} OR {$search_core} )";
+
+	$sql['where']['search'] = $search_combined;
+
+	return $sql;
+}
+add_action( 'bp_user_query_uid_clauses', 'bp_xprofile_bp_user_query_search', 10, 2 );
+
 /**
  * Syncs Xprofile data to the standard built in WordPress profile data.
  *
@@ -437,7 +545,7 @@ function xprofile_sync_wp_profile( $user_id = 0 ) {
 	if ( empty( $user_id ) )
 		return false;
 
-	$fullname = xprofile_get_field_data( bp_xprofile_fullname_field_name(), $user_id );
+	$fullname = xprofile_get_field_data( bp_xprofile_fullname_field_id(), $user_id );
 	$space    = strpos( $fullname, ' ' );
 
 	if ( false === $space ) {
@@ -473,7 +581,7 @@ function xprofile_sync_bp_profile( &$errors, $update, &$user ) {
 	if ( ( !empty( $bp->site_options['bp-disable-profile-sync'] ) && (int) $bp->site_options['bp-disable-profile-sync'] ) || !$update || $errors->get_error_codes() )
 		return;
 
-	xprofile_set_field_data( bp_xprofile_fullname_field_name(), $user->ID, $user->display_name );
+	xprofile_set_field_data( bp_xprofile_fullname_field_id(), $user->ID, $user->display_name );
 }
 add_action( 'user_profile_update_errors', 'xprofile_sync_bp_profile', 10, 3 );
 
@@ -495,120 +603,131 @@ add_action( 'bp_make_spam_user', 'xprofile_remove_data' );
 
 /*** XProfile Meta ****************************************************/
 
-function bp_xprofile_delete_meta( $object_id, $object_type, $meta_key = false, $meta_value = false ) {
-	global $wpdb, $bp;
-
-	$object_id = (int) $object_id;
-
-	if ( !$object_id )
-		return false;
-
-	if ( !isset( $object_type ) )
-		return false;
+/**
+ * Delete a piece of xprofile metadata.
+ *
+ * @param int $object_id ID of the object the metadata belongs to.
+ * @param string $object_type Type of object. 'group', 'field', or 'data'.
+ * @param string $meta_key Key of the metadata being deleted. If omitted, all
+ *        metadata for the object will be deleted.
+ * @param mixed $meta_value Optional. If provided, only metadata that matches
+ *        the value will be permitted.
+ * @param bool $delete_all Optional. If true, delete matching metadata entries
+ * 	  for all objects, ignoring the specified object_id. Otherwise, only
+ * 	  delete matching metadata entries for the specified object.
+ * 	  Default: false.
+ * @return bool True on success, false on failure.
+ */
+function bp_xprofile_delete_meta( $object_id, $object_type, $meta_key = false, $meta_value = false, $delete_all = false ) {
+	global $wpdb;
 
-	if ( !in_array( $object_type, array( 'group', 'field', 'data' ) ) )
+	// Sanitize object type
+	if ( ! in_array( $object_type, array( 'group', 'field', 'data' ) ) ) {
 		return false;
-
-	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-	if ( is_array( $meta_value ) || is_object( $meta_value ) ) {
-		$meta_value = serialize( $meta_value );
 	}
 
-	$meta_value = trim( $meta_value );
-
+	// Legacy - if no meta_key is passed, delete all for the item
 	if ( empty( $meta_key ) ) {
-		$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_meta} WHERE object_id = %d AND object_type = %s", $object_id, $object_type ) );
-	} elseif ( !empty( $meta_value ) ) {
-		$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_meta} WHERE object_id = %d AND object_type = %s AND meta_key = %s AND meta_value = %s", $object_id, $object_type, $meta_key, $meta_value ) );
-	} else {
-		$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_meta} WHERE object_id = %d AND object_type = %s AND meta_key = %s", $object_id, $object_type, $meta_key ) );
-	}
-
-	// Delete the cached object
-	wp_cache_delete( 'bp_xprofile_meta_' . $object_type . '_' . $object_id . '_' . $meta_key, 'bp' );
-
-	return true;
-}
+		$table_key  = 'xprofile_' . $object_type . 'meta';
+		$table_name = $wpdb->{$table_key};
+		$keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$table_name} WHERE object_type = %s AND object_id = %d", $object_type, $object_id ) );
 
-function bp_xprofile_get_meta( $object_id, $object_type, $meta_key = '') {
-	global $wpdb, $bp;
-
-	$object_id = (int) $object_id;
-
-	if ( !$object_id )
-		return false;
-
-	if ( !isset( $object_type ) )
-		return false;
-
-	if ( !in_array( $object_type, array( 'group', 'field', 'data' ) ) )
-		return false;
-
-	if ( !empty( $meta_key ) ) {
-		$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-		if ( !$metas = wp_cache_get( 'bp_xprofile_meta_' . $object_type . '_' . $object_id . '_' . $meta_key, 'bp' ) ) {
-			$metas = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM {$bp->profile->table_name_meta} WHERE object_id = %d AND object_type = %s AND meta_key = %s", $object_id, $object_type, $meta_key ) );
-			wp_cache_set( 'bp_xprofile_meta_' . $object_type . '_' . $object_id . '_' . $meta_key, $metas, 'bp' );
-		}
+		// Force delete_all to false if deleting all for object
+		$delete_all = false;
 	} else {
-		$metas = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM {$bp->profile->table_name_meta} WHERE object_id = %d AND object_type = %s", $object_id, $object_type ) );
+		$keys = array( $meta_key );
 	}
 
-	if ( empty( $metas ) ) {
-		if ( empty( $meta_key ) ) {
-			return array();
-		} else {
-			return '';
-		}
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	add_filter( 'query', 'bp_xprofile_filter_meta_query' );
+
+	$retval = false;
+	foreach ( $keys as $key ) {
+		$retval = delete_metadata( 'xprofile_' . $object_type, $object_id, $key, $meta_value, $delete_all );
 	}
 
-	$metas = array_map( 'maybe_unserialize', (array) $metas );
+	remove_filter( 'query', 'bp_xprofile_filter_meta_query' );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
 
-	if ( 1 == count( $metas ) )
-		return $metas[0];
-	else
-		return $metas;
+	return $retval;
 }
 
-function bp_xprofile_update_meta( $object_id, $object_type, $meta_key, $meta_value ) {
-	global $wpdb, $bp;
-
-	$object_id = (int) $object_id;
-
-	if ( empty( $object_id ) )
-		return false;
-
-	if ( !isset( $object_type ) )
-		return false;
-
-	if ( !in_array( $object_type, array( 'group', 'field', 'data' ) ) )
+/**
+ * Get a piece of xprofile metadata.
+ *
+ * Note that the default value of $single is true, unlike in the case of the
+ * underlying get_metadata() function. This is for backward compatibility.
+ *
+ * @param int $object_id ID of the object the metadata belongs to.
+ * @param string $object_type Type of object. 'group', 'field', or 'data'.
+ * @param string $meta_key Key of the metadata being fetched. If omitted, all
+ *        metadata for the object will be retrieved.
+ * @param bool $single Optional. If true, return only the first value of the
+ *	  specified meta_key. This parameter has no effect if meta_key is not
+ *	  specified. Default: true.
+ * @return mixed Meta value if found. False on failure.
+ */
+function bp_xprofile_get_meta( $object_id, $object_type, $meta_key = '', $single = true ) {
+	// Sanitize object type
+	if ( ! in_array( $object_type, array( 'group', 'field', 'data' ) ) ) {
 		return false;
+	}
 
-	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
-
-	if ( is_string( $meta_value ) )
-		$meta_value = stripslashes( esc_sql( $meta_value ) );
-
-	$meta_value = maybe_serialize( $meta_value );
-
-	if ( empty( $meta_value ) )
-		return bp_xprofile_delete_meta( $object_id, $object_type, $meta_key );
-
-	$cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->profile->table_name_meta} WHERE object_id = %d AND object_type = %s AND meta_key = %s", $object_id, $object_type, $meta_key ) );
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	add_filter( 'query', 'bp_xprofile_filter_meta_query' );
+	$retval = get_metadata( 'xprofile_' . $object_type, $object_id, $meta_key, $single );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
+	remove_filter( 'query', 'bp_xprofile_filter_meta_query' );
 
-	if ( empty( $cur ) )
-		$wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->profile->table_name_meta} ( object_id, object_type, meta_key, meta_value ) VALUES ( %d, %s, %s, %s )", $object_id, $object_type,  $meta_key, $meta_value ) );
-	else if ( $cur->meta_value != $meta_value )
-		$wpdb->query( $wpdb->prepare( "UPDATE {$bp->profile->table_name_meta} SET meta_value = %s WHERE object_id = %d AND object_type = %s AND meta_key = %s", $meta_value, $object_id, $object_type, $meta_key ) );
-	else
-		return false;
+	return $retval;
+}
 
-	// Update the cached object and recache
-	wp_cache_set( 'bp_xprofile_meta_' . $object_type . '_' . $object_id . '_' . $meta_key, $meta_value, 'bp' );
+/**
+ * Update a piece of xprofile metadata.
+ *
+ * @param int $object_id ID of the object the metadata belongs to.
+ * @param string $object_type Type of object. 'group', 'field', or 'data'.
+ * @param string $meta_key Key of the metadata being updated.
+ * @param mixed $meta_value Value of the metadata being updated.
+ * @param mixed $prev_value Optional. If specified, only update existing
+ *        metadata entries with the specified value. Otherwise, update all
+ *        entries.
+ * @return bool|int Returns false on failure. On successful update of existing
+ *         metadata, returns true. On successful creation of new metadata,
+ *         returns the integer ID of the new metadata row.
+ */
+function bp_xprofile_update_meta( $object_id, $object_type, $meta_key, $meta_value, $prev_value = '' ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	add_filter( 'query', 'bp_xprofile_filter_meta_query' );
+	$retval = update_metadata( 'xprofile_' . $object_type, $object_id, $meta_key, $meta_value, $prev_value );
+	remove_filter( 'query', 'bp_xprofile_filter_meta_query' );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
+
+	return $retval;
+}
 
-	return true;
+/**
+ * Add a piece of xprofile metadata.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param int $object_id ID of the object the metadata belongs to.
+ * @param string $object_type Type of object. 'group', 'field', or 'data'.
+ * @param string $meta_key Metadata key.
+ * @param mixed $meta_value Metadata value.
+ * @param bool $unique. Optional. Whether to enforce a single metadata value
+ *        for the given key. If true, and the object already has a value for
+ *        the key, no change will be made. Default: false.
+ * @return int|bool The meta ID on successful update, false on failure.
+ */
+function bp_xprofile_add_meta( $object_id, $object_type, $meta_key, $meta_value, $unique = false ) {
+	add_filter( 'query', 'bp_filter_metaid_column_name' );
+	add_filter( 'query', 'bp_xprofile_filter_meta_query' );
+	$retval = add_metadata( 'xprofile_' . $object_type , $object_id, $meta_key, $meta_value, $unique );
+	remove_filter( 'query', 'bp_filter_metaid_column_name' );
+	remove_filter( 'query', 'bp_xprofile_filter_meta_query' );
+
+	return $retval;
 }
 
 function bp_xprofile_update_fieldgroup_meta( $field_group_id, $meta_key, $meta_value ) {
@@ -623,6 +742,28 @@ function bp_xprofile_update_fielddata_meta( $field_data_id, $meta_key, $meta_val
 	return bp_xprofile_update_meta( $field_data_id, 'data', $meta_key, $meta_value );
 }
 
+/**
+ * Return the field ID for the Full Name xprofile field.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return int Field ID.
+ */
+function bp_xprofile_fullname_field_id() {
+	$id = wp_cache_get( 'fullname_field_id', 'bp_xprofile' );
+
+	if ( false === $id ) {
+		global $wpdb;
+
+		$bp = buddypress();
+		$id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", bp_xprofile_fullname_field_name() ) );
+
+		wp_cache_set( 'fullname_field_id', $id, 'bp_xprofile' );
+	}
+
+	return absint( $id );
+}
+
 /**
  * Return the field name for the Full Name xprofile field
  *
@@ -677,38 +818,53 @@ function bp_xprofile_get_hidden_fields_for_user( $displayed_user_id = 0, $curren
 	}
 
 	// @todo - This is where you'd swap out for current_user_can() checks
-	$hidden_levels = $hidden_fields = array();
+	$hidden_levels = bp_xprofile_get_hidden_field_types_for_user( $displayed_user_id, $current_user_id );
+	$hidden_fields = bp_xprofile_get_fields_by_visibility_levels( $displayed_user_id, $hidden_levels );
+
+	return apply_filters( 'bp_xprofile_get_hidden_fields_for_user', $hidden_fields, $displayed_user_id, $current_user_id );
+}
+
+/**
+ * Get the visibility levels that should be hidden for this user pair
+ *
+ * Field visibility is determined based on the relationship between the
+ * logged-in user, the displayed user, and the visibility setting for the
+ * current field. (See bp_xprofile_get_hidden_fields_for_user().) This
+ * utility function speeds up this matching by fetching the visibility levels
+ * that should be hidden for the current user pair.
+ *
+ * @since BuddyPress (1.8.2)
+ * @see bp_xprofile_get_hidden_fields_for_user()
+ *
+ * @param int $displayed_user_id The id of the user the profile fields belong to
+ * @param int $current_user_id The id of the user viewing the profile
+ * @return array An array of visibility levels hidden to the current user
+ */
+function bp_xprofile_get_hidden_field_types_for_user( $displayed_user_id = 0, $current_user_id = 0 ) {
 
 	// Current user is logged in
-	if ( $current_user_id ) {
+	if ( ! empty( $current_user_id ) ) {
 
-		// If you're viewing your own profile, nothing's private
-		if ( $displayed_user_id == $current_user_id ) {
+		// Nothing's private when viewing your own profile, or when the
+		// current user is an admin
+		if ( $displayed_user_id == $current_user_id || bp_current_user_can( 'bp_moderate' ) ) {
+			$hidden_levels = array();
 
 		// If the current user and displayed user are friends, show all
 		} elseif ( bp_is_active( 'friends' ) && friends_check_friendship( $displayed_user_id, $current_user_id ) ) {
-			if ( ! bp_current_user_can( 'bp_moderate' ) )
-				$hidden_levels[] = 'adminsonly';
+			$hidden_levels = array( 'adminsonly', );
 
-			$hidden_fields = bp_xprofile_get_fields_by_visibility_levels( $displayed_user_id, $hidden_levels );
-
-		// current user is logged-in but not friends, so exclude friends-only
+		// current user is logged in but not friends, so exclude friends-only
 		} else {
-			$hidden_levels = array( 'friends' );
-
-			if ( ! bp_current_user_can( 'bp_moderate' ) )
-				$hidden_levels[] = 'adminsonly';
-
-			$hidden_fields = bp_xprofile_get_fields_by_visibility_levels( $displayed_user_id, $hidden_levels );
+			$hidden_levels = array( 'friends', 'adminsonly', );
 		}
 
 	// Current user is not logged in, so exclude friends-only, loggedin, and adminsonly.
 	} else {
 		$hidden_levels = array( 'friends', 'loggedin', 'adminsonly', );
-		$hidden_fields = bp_xprofile_get_fields_by_visibility_levels( $displayed_user_id, $hidden_levels );
 	}
 
-	return apply_filters( 'bp_xprofile_get_hidden_fields_for_user', $hidden_fields, $displayed_user_id, $current_user_id );
+	return apply_filters( 'bp_xprofile_get_hidden_field_types_for_user', $hidden_levels, $displayed_user_id, $current_user_id );
 }
 
 /**
@@ -736,7 +892,7 @@ function bp_xprofile_get_fields_by_visibility_levels( $user_id, $levels = array(
 	foreach( (array) $default_visibility_levels as $d_field_id => $defaults ) {
 		// If the admin has forbidden custom visibility levels for this field, replace
 		// the user-provided setting with the default specified by the admin
-		if ( isset( $defaults['allow_custom'] ) && isset( $defaults['default'] ) && 'disabled' == $defaults['allow_custom'] && isset( $user_visibility_levels[$d_field_id] ) ) {
+		if ( isset( $defaults['allow_custom'] ) && isset( $defaults['default'] ) && 'disabled' == $defaults['allow_custom'] ) {
 			$user_visibility_levels[$d_field_id] = $defaults['default'];
 		}
 	}
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-loader.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-loader.php
index 303026531a98f26874000f551571c2b3e238d965..71d84e30c1e21815e89c53c0af276f0b0722e7bf 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-loader.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-loader.php
@@ -35,12 +35,17 @@ class BP_XProfile_Component extends BP_Component {
 	 *
 	 * @since BuddyPress (1.5)
 	 */
-	function __construct() {
+	public function __construct() {
 		parent::start(
 			'xprofile',
 			__( 'Extended Profiles', 'buddypress' ),
-			BP_PLUGIN_DIR
+			buddypress()->plugin_dir,
+			array(
+				'adminbar_myaccount_order' => 20
+			)
 		);
+
+		$this->setup_hooks();
 	}
 
 	/**
@@ -56,6 +61,7 @@ class BP_XProfile_Component extends BP_Component {
 			'caps',
 			'classes',
 			'filters',
+			'settings',
 			'template',
 			'buddybar',
 			'functions',
@@ -74,45 +80,42 @@ class BP_XProfile_Component extends BP_Component {
 	 * backwards compatibility.
 	 *
 	 * @since BuddyPress (1.5)
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_globals( $args = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		// Define a slug, if necessary
 		if ( !defined( 'BP_XPROFILE_SLUG' ) )
 			define( 'BP_XPROFILE_SLUG', 'profile' );
 
-		// Assign the base group and fullname field names to constants to use
-		// in SQL statements
-		define ( 'BP_XPROFILE_BASE_GROUP_NAME',     stripslashes( $bp->site_options['bp-xprofile-base-group-name']     ) );
-		define ( 'BP_XPROFILE_FULLNAME_FIELD_NAME', stripslashes( $bp->site_options['bp-xprofile-fullname-field-name'] ) );
+		// Assign the base group and fullname field names to constants
+		// to use in SQL statements.
+		// Defined conditionally to accommodate unit tests
+		if ( ! defined( 'BP_XPROFILE_BASE_GROUP_NAME' ) ) {
+			define( 'BP_XPROFILE_BASE_GROUP_NAME', stripslashes( $bp->site_options['bp-xprofile-base-group-name'] ) );
+		}
+
+		if ( ! defined( 'BP_XPROFILE_FULLNAME_FIELD_NAME' ) ) {
+			define( 'BP_XPROFILE_FULLNAME_FIELD_NAME', stripslashes( $bp->site_options['bp-xprofile-fullname-field-name'] ) );
+		}
 
 		// Set the support field type ids
-		$this->field_types = apply_filters( 'xprofile_field_types', array(
-			'textbox',
-			'textarea',
-			'radio',
-			'checkbox',
-			'selectbox',
-			'multiselectbox',
-			'datebox'
-		) );
+		$this->field_types = apply_filters( 'xprofile_field_types', array_keys( bp_xprofile_get_field_types() ) );
 
 		// Register the visibility levels. See bp_xprofile_get_visibility_levels() to filter
 		$this->visibility_levels = array(
 			'public' => array(
 				'id'	  => 'public',
-				'label' => __( 'Anyone', 'buddypress' )
-			),
-			'loggedin' => array(
-				'id'	  => 'loggedin',
-				'label' => __( 'Logged In Users', 'buddypress' )
+				'label' => __( 'Everyone', 'buddypress' )
 			),
 			'adminsonly' => array(
 				'id'	  => 'adminsonly',
-				'label' => __( 'Admins Only', 'buddypress' )
+				'label' => __( 'Only Me', 'buddypress' )
 			),
+			'loggedin' => array(
+				'id'	  => 'loggedin',
+				'label' => __( 'All Members', 'buddypress' )
+			)
 		);
 
 		if ( bp_is_active( 'friends' ) ) {
@@ -130,11 +133,18 @@ class BP_XProfile_Component extends BP_Component {
 			'table_name_meta'   => $bp->table_prefix . 'bp_xprofile_meta',
 		);
 
+		$meta_tables = array(
+			'xprofile_group' => $bp->table_prefix . 'bp_xprofile_meta',
+			'xprofile_field' => $bp->table_prefix . 'bp_xprofile_meta',
+			'xprofile_data'  => $bp->table_prefix . 'bp_xprofile_meta',
+		);
+
 		$globals = array(
 			'slug'                  => BP_XPROFILE_SLUG,
 			'has_directory'         => false,
 			'notification_callback' => 'xprofile_format_notifications',
-			'global_tables'         => $global_tables
+			'global_tables'         => $global_tables,
+			'meta_tables'           => $meta_tables,
 		);
 
 		parent::setup_globals( $globals );
@@ -192,26 +202,44 @@ class BP_XProfile_Component extends BP_Component {
 		);
 
 		// Change Avatar
-		$sub_nav[] = array(
-			'name'            => __( 'Change Avatar', 'buddypress' ),
-			'slug'            => 'change-avatar',
-			'parent_url'      => $profile_link,
-			'parent_slug'     => $this->slug,
-			'screen_function' => 'xprofile_screen_change_avatar',
-			'position'        => 30,
-			'user_has_access' => bp_core_can_edit_settings()
-		);
+		if ( buddypress()->avatar->show_avatars ) {
+			$sub_nav[] = array(
+				'name'            => __( 'Change Avatar', 'buddypress' ),
+				'slug'            => 'change-avatar',
+				'parent_url'      => $profile_link,
+				'parent_slug'     => $this->slug,
+				'screen_function' => 'xprofile_screen_change_avatar',
+				'position'        => 30,
+				'user_has_access' => bp_core_can_edit_settings()
+			);
+		}
+
+		// Privacy Settings
+		if ( bp_is_active( 'settings' ) ) {
+
+			// Get the settings slug
+			$settings_slug = bp_get_settings_slug();
+
+			// Add the sub-navigation
+			$sub_nav[] = array(
+				'name'            => __( 'Profile', 'buddypress' ),
+				'slug'            => 'profile',
+				'parent_url'      => trailingslashit( $user_domain . $settings_slug ),
+				'parent_slug'     => $settings_slug,
+				'screen_function' => 'bp_xprofile_screen_settings',
+				'position'        => 30,
+				'user_has_access' => bp_core_can_edit_settings()
+			);
+		}
 
 		parent::setup_nav( $main_nav, $sub_nav );
 	}
 
 	/**
 	 * Set up the Toolbar
-	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
 	 */
 	public function setup_admin_bar( $wp_admin_nav = array() ) {
-		global $bp;
+		$bp = buddypress();
 
 		// Prevent debug notices
 		$wp_admin_nav = array();
@@ -246,13 +274,15 @@ class BP_XProfile_Component extends BP_Component {
 				'href'   => trailingslashit( $profile_link . 'edit' )
 			);
 
-			// Edit Profile
-			$wp_admin_nav[] = array(
-				'parent' => 'my-account-' . $this->id,
-				'id'     => 'my-account-' . $this->id . '-change-avatar',
-				'title'  => __( 'Change Avatar', 'buddypress' ),
-				'href'   => trailingslashit( $profile_link . 'change-avatar' )
-			);
+			// Edit Avatar
+			if ( buddypress()->avatar->show_avatars ) {
+				$wp_admin_nav[] = array(
+					'parent' => 'my-account-' . $this->id,
+					'id'     => 'my-account-' . $this->id . '-change-avatar',
+					'title'  => __( 'Change Avatar', 'buddypress' ),
+					'href'   => trailingslashit( $profile_link . 'change-avatar' )
+				);
+			}
 
 		}
 
@@ -260,12 +290,19 @@ class BP_XProfile_Component extends BP_Component {
 	}
 
 	/**
-	 * Sets up the title for pages and <title>
+	 * Add custom hooks.
 	 *
-	 * @global BuddyPress $bp The one true BuddyPress instance
+	 * @since BuddyPress (2.0.0)
+	 */
+	public function setup_hooks() {
+		add_filter( 'bp_settings_admin_nav', array( $this, 'setup_settings_admin_nav' ), 2 );
+	}
+
+	/**
+	 * Sets up the title for pages and <title>
 	 */
-	function setup_title() {
-		global $bp;
+	public function setup_title() {
+		$bp = buddypress();
 
 		if ( bp_is_profile_component() ) {
 			if ( bp_is_my_profile() ) {
@@ -282,10 +319,33 @@ class BP_XProfile_Component extends BP_Component {
 
 		parent::setup_title();
 	}
+
+	/**
+	 * Adds "Settings > Profile" subnav item under the "Settings" adminbar menu.
+	 *
+	 * @since BuddyPress (2.0.0)
+	 *
+	 * @param array $wp_admin_nav The settings adminbar nav array.
+	 * @return array
+	 */
+	public function setup_settings_admin_nav( $wp_admin_nav ) {
+		// Setup the logged in user variables
+		$settings_link = trailingslashit( bp_loggedin_user_domain() . bp_get_settings_slug() );
+
+		// Add the "Profile" subnav item
+		$wp_admin_nav[] = array(
+			'parent' => 'my-account-' . buddypress()->settings->id,
+			'id'     => 'my-account-' . buddypress()->settings->id . '-profile',
+			'title'  => __( 'Profile', 'buddypress' ),
+			'href'   => trailingslashit( $settings_link . 'profile' )
+		);
+
+		return $wp_admin_nav;
+	}
 }
 
 function bp_setup_xprofile() {
-	global $bp;
+	$bp = buddypress();
 
 	if ( !isset( $bp->profile->id ) )
 		$bp->profile = new BP_XProfile_Component();
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-screens.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-screens.php
index 6c3bceefabe306b4d1c16ce193391536a40a9938..4eea462a62436be9718473a9ffba69fd2062e69a 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-screens.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-screens.php
@@ -67,7 +67,7 @@ function xprofile_screen_edit_profile() {
 
 		// Explode the posted field IDs into an array so we know which
 		// fields have been submitted
-		$posted_field_ids = explode( ',', $_POST['field_ids'] );
+		$posted_field_ids = wp_parse_id_list( $_POST['field_ids'] );
 		$is_required      = array();
 
 		// Loop through the posted fields formatting any datebox values
@@ -102,14 +102,11 @@ function xprofile_screen_edit_profile() {
 			$errors = false;
 
 			// Now we've checked for required fields, lets save the values.
+			$old_values = $new_values = array();
 			foreach ( (array) $posted_field_ids as $field_id ) {
 
 				// Certain types of fields (checkboxes, multiselects) may come through empty. Save them as an empty array so that they don't get overwritten by the default on the next edit.
-				if ( empty( $_POST['field_' . $field_id] ) ) {
-					$value = array();
-				} else {
-					$value = $_POST['field_' . $field_id];
-				}
+				$value = isset( $_POST['field_' . $field_id] ) ? $_POST['field_' . $field_id] : '';
 
 				if ( !xprofile_set_field_data( $field_id, bp_displayed_user_id(), $value, $is_required[$field_id] ) ) {
 					$errors = true;
@@ -120,9 +117,21 @@ function xprofile_screen_edit_profile() {
 				// Save the visibility level
 				$visibility_level = !empty( $_POST['field_' . $field_id . '_visibility'] ) ? $_POST['field_' . $field_id . '_visibility'] : 'public';
 				xprofile_set_field_visibility_level( $field_id, bp_displayed_user_id(), $visibility_level );
+
+				// Save the old and new values. They will be
+				// passed to the filter and used to determine
+				// whether an activity item should be posted
+				$old_values[ $field_id ] = array(
+					'value'      => xprofile_get_field_data( $field_id, bp_displayed_user_id() ),
+					'visibility' => xprofile_get_field_visibility_level( $field_id, bp_displayed_user_id() ),
+				);
+				$new_values[ $field_id ] = array(
+					'value'      => $value,
+					'visibility' => $visibility_level,
+				);
 			}
 
-			do_action( 'xprofile_updated_profile', bp_displayed_user_id(), $posted_field_ids, $errors );
+			do_action( 'xprofile_updated_profile', bp_displayed_user_id(), $posted_field_ids, $errors, $old_values, $new_values );
 
 			// Set the feedback messages
 			if ( !empty( $errors ) ) {
@@ -198,8 +207,9 @@ function xprofile_screen_change_avatar() {
 		if ( ! bp_core_avatar_handle_crop( $args ) ) {
 			bp_core_add_message( __( 'There was a problem cropping your avatar.', 'buddypress' ), 'error' );
 		} else {
-			bp_core_add_message( __( 'Your new avatar was uploaded successfully.', 'buddypress' ) );
 			do_action( 'xprofile_avatar_uploaded' );
+			bp_core_add_message( __( 'Your new avatar was uploaded successfully.', 'buddypress' ) );
+			bp_core_redirect( bp_loggedin_user_domain() );
 		}
 	}
 
@@ -207,3 +217,20 @@ function xprofile_screen_change_avatar() {
 
 	bp_core_load_template( apply_filters( 'xprofile_template_change_avatar', 'members/single/home' ) );
 }
+
+/**
+ * Show the xprofile settings template
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_xprofile_screen_settings() {
+
+	// Redirect if no privacy settings page is accessible
+	if ( bp_action_variables() || ! bp_is_active( 'xprofile' ) ) {
+		bp_do_404();
+		return;
+	}
+
+	// Load the template
+	bp_core_load_template( apply_filters( 'bp_settings_screen_xprofile', '/members/single/plugin' ) );
+}
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-settings.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-settings.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5ade72e896ffb5b6314635a5d21f4f5b4bc8942
--- /dev/null
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-settings.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Query all profile fields and their visibility data for display in settings
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @param array $args
+ * 
+ * 
+ * @return array
+ */
+function bp_xprofile_get_settings_fields( $args = '' ) {
+
+	// Parse the possible arguments
+	$r = bp_parse_args( $args, array(
+		'user_id'                => bp_displayed_user_id(),
+		'profile_group_id'       => false,
+		'hide_empty_groups'      => false,
+		'hide_empty_fields'      => false,
+		'fetch_fields'           => true,
+		'fetch_field_data'       => false,
+		'fetch_visibility_level' => true,
+		'exclude_groups'         => false,
+		'exclude_fields'         => false
+	), 'xprofile_get_settings_fields' );
+
+	return bp_has_profile( $r );
+}
+
+/**
+ * Adds feedback messages when successfully saving profile field settings
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @uses bp_core_add_message()
+ * @usse bp_is_my_profile()
+ */
+function bp_xprofile_settings_add_feedback_message() {
+
+	// Default message type is success
+	$type    = 'success';
+	$message = __( 'Your profile settings have been saved.',        'buddypress' );
+
+	// Community moderator editing another user's settings
+	if ( ! bp_is_my_profile() && bp_core_can_edit_settings() ) {
+		$message = __( "This member's profile settings have been saved.", 'buddypress' );
+	}
+
+	// Add the message
+	bp_core_add_message( $message, $type );
+}
+add_action( 'bp_xprofile_settings_after_save', 'bp_xprofile_settings_add_feedback_message' );
diff --git a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-template.php b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-template.php
index 4370d5ffcf5b8255f448dd4dce63d72372d3f97b..1d6931357ed3d8a85828bc9631d8fe43aa77ed7d 100644
--- a/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-template.php
+++ b/wp-content/plugins/buddypress/bp-xprofile/bp-xprofile-template.php
@@ -24,7 +24,7 @@ class BP_XProfile_Data_Template {
 	var $in_the_loop;
 	var $user_id;
 
-	function __construct( $user_id, $profile_group_id, $hide_empty_groups = false, $fetch_fields = false, $fetch_field_data = false, $exclude_groups = false, $exclude_fields = false, $hide_empty_fields = false, $fetch_visibility_level = false ) {
+	function __construct( $user_id, $profile_group_id, $hide_empty_groups = false, $fetch_fields = false, $fetch_field_data = false, $exclude_groups = false, $exclude_fields = false, $hide_empty_fields = false, $fetch_visibility_level = false, $update_meta_cache = true ) {
 		$this->groups = BP_XProfile_Group::get( array(
 			'profile_group_id'    => $profile_group_id,
 			'user_id'             => $user_id,
@@ -34,7 +34,8 @@ class BP_XProfile_Data_Template {
 			'fetch_field_data'    => $fetch_field_data,
 			'fetch_visibility_level' => $fetch_visibility_level,
 			'exclude_groups'      => $exclude_groups,
-			'exclude_fields'      => $exclude_fields
+			'exclude_fields'      => $exclude_fields,
+			'update_meta_cache'   => $update_meta_cache,
 		) );
 
 		$this->group_count = count($this->groups);
@@ -51,9 +52,13 @@ class BP_XProfile_Data_Template {
 	function next_group() {
 		$this->current_group++;
 
-		$this->group         = $this->groups[$this->current_group];
-		$this->group->fields = apply_filters( 'xprofile_group_fields', $this->group->fields, $this->group->id );
-		$this->field_count   = count( $this->group->fields );
+		$this->group       = $this->groups[$this->current_group];
+		$this->field_count = 0;
+
+		if( ! empty( $this->group->fields ) ) {
+			$this->group->fields = apply_filters( 'xprofile_group_fields', $this->group->fields, $this->group->id );
+			$this->field_count   = count( $this->group->fields );
+		}
 
 		return $this->group;
 	}
@@ -170,13 +175,14 @@ function bp_has_profile( $args = '' ) {
 		'fetch_field_data'    => true,
 		'fetch_visibility_level' => $fetch_visibility_level_default,
 		'exclude_groups'      => false, // Comma-separated list of profile field group IDs to exclude
-		'exclude_fields'      => false  // Comma-separated list of profile field IDs to exclude
+		'exclude_fields'      => false,  // Comma-separated list of profile field IDs to exclude
+		'update_meta_cache'   => true,
 	);
 
-	$r = wp_parse_args( $args, $defaults );
+	$r = bp_parse_args( $args, $defaults, 'has_profile' );
 	extract( $r, EXTR_SKIP );
 
-	$profile_template = new BP_XProfile_Data_Template( $user_id, $profile_group_id, $hide_empty_groups, $fetch_fields, $fetch_field_data, $exclude_groups, $exclude_fields, $hide_empty_fields, $fetch_visibility_level );
+	$profile_template = new BP_XProfile_Data_Template( $user_id, $profile_group_id, $hide_empty_groups, $fetch_fields, $fetch_field_data, $exclude_groups, $exclude_fields, $hide_empty_fields, $fetch_visibility_level, $update_meta_cache );
 	return apply_filters( 'bp_has_profile', $profile_template->has_groups(), $profile_template );
 }
 
@@ -215,6 +221,7 @@ function bp_field_css_class( $class = false ) {
 		if ( $profile_template->current_field % 2 == 1 )
 			$css_classes[] = 'alt';
 
+		$css_classes[] = 'field_type_' . sanitize_title( $profile_template->field->type );
 		$css_classes = apply_filters_ref_array( 'bp_field_css_classes', array( &$css_classes ) );
 
 		return apply_filters( 'bp_get_field_css_class', ' class="' . implode( ' ', $css_classes ) . '"' );
@@ -263,7 +270,7 @@ function bp_the_profile_group_description() {
 }
 	function bp_get_the_profile_group_description() {
 		global $group;
-		echo apply_filters( 'bp_get_the_profile_group_description', $group->description );
+		return apply_filters( 'bp_get_the_profile_group_description', $group->description );
 	}
 
 function bp_the_profile_group_edit_form_action() {
@@ -282,8 +289,12 @@ function bp_the_profile_group_field_ids() {
 		global $group;
 
 		$field_ids = '';
-		foreach ( (array) $group->fields as $field )
-			$field_ids .= $field->id . ',';
+
+		if ( !empty( $group->fields ) ) {
+			foreach ( (array) $group->fields as $field ) {
+				$field_ids .= $field->id . ',';
+			}
+		}
 
 		return substr( $field_ids, 0, -1 );
 	}
@@ -380,11 +391,7 @@ function bp_the_profile_field_input_name() {
 	function bp_get_the_profile_field_input_name() {
 		global $field;
 
-		$array_box = false;
-		if ( 'multiselectbox' == $field->type )
-			$array_box = '[]';
-
-		return apply_filters( 'bp_get_the_profile_field_input_name', 'field_' . $field->id . $array_box );
+		return apply_filters( 'bp_get_the_profile_field_input_name', 'field_' . $field->id );
 	}
 
 /**
@@ -417,14 +424,13 @@ function bp_get_the_profile_field_errors_action() {
  *
  * @param array $args Specify type for datebox. Allowed 'day', 'month', 'year'.
  */
-function bp_the_profile_field_options( $args = '' ) {
+function bp_the_profile_field_options( $args = array() ) {
 	echo bp_get_the_profile_field_options( $args );
 }
 	/**
 	 * bp_get_the_profile_field_options()
 	 *
-	 * Retrieves field options HTML for field types of 'selectbox', 'multiselectbox',
-	 * 'radio', 'checkbox', and 'datebox'.
+	 * Retrieves field options HTML for field types of 'selectbox', 'multiselectbox', 'radio', 'checkbox', and 'datebox'.
 	 *
 	 * @package BuddyPress Xprofile
 	 * @since BuddyPress (1.1)
@@ -432,286 +438,41 @@ function bp_the_profile_field_options( $args = '' ) {
 	 * @uses BP_XProfile_Field::get_children()
 	 * @uses BP_XProfile_ProfileData::get_value_byid()
 	 *
-	 * @param array $args Specify type for datebox. Allowed 'day', 'month', 'year'.
+	 * @param array $args {
+	 *     Array of optional arguments.
+	 *     @type string|bool $type Type of datebox. False if it's not a
+	 *           datebox, otherwise 'day, 'month', or 'year'. Default: false.
+	 *     @type int $user_id ID of the user whose profile values should be
+	 *           used when rendering options. Default: displayed user.
+	 * }
 	 */
-	function bp_get_the_profile_field_options( $args = '' ) {
+	function bp_get_the_profile_field_options( $args = array() ) {
 		global $field;
 
-		// Generally a required dropdown field will not get a blank value at
-		// the top. Set 'null_on_required' to true if you want this blank value
-		// even on required fields.
-		$defaults = array(
-			'type' 		       => false,
-			'null_on_required' => false
-		);
-
-		$r = wp_parse_args( $args, $defaults );
-		extract( $r, EXTR_SKIP );
+		$args = bp_parse_args( $args, array(
+			'type'    => false,
+			'user_id' => bp_displayed_user_id(),
+		), 'get_the_profile_field_options' );
 
-		// In some cases, the $field global is not an instantiation of the BP_XProfile_Field
-		// class. However, we have to make sure that all data originally in $field gets
-		// merged back in, after reinstantiation.
-		if ( !method_exists( $field, 'get_children' ) ) {
+		/**
+		 * In some cases, the $field global is not an instantiation of the BP_XProfile_Field class.
+		 * However, we have to make sure that all data originally in $field gets merged back in, after reinstantiation.
+		 */
+		if ( ! method_exists( $field, 'get_children' ) ) {
 			$field_obj = new BP_XProfile_Field( $field->id );
 
-			foreach( $field as $field_prop => $field_prop_value ) {
-				if ( !isset( $field_obj->{$field_prop} ) ) {
+			foreach ( $field as $field_prop => $field_prop_value ) {
+				if ( ! isset( $field_obj->{$field_prop} ) )
 					$field_obj->{$field_prop} = $field_prop_value;
-				}
 			}
 
 			$field = $field_obj;
 		}
 
-		$options = $field->get_children();
-
-		// Setup some defaults
-		$html     = '';
-		$selected = '';
-
-		switch ( $field->type ) {
-			case 'selectbox':
-
-				if ( !$field->is_required || $null_on_required ) {
-					$html .= '<option value="">' . /* translators: no option picked in select box */ __( '----', 'buddypress' ) . '</option>';
-				}
-
-				$original_option_values = '';
-				$original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $field->id ) );
-
-				if ( empty( $original_option_values ) && !empty( $_POST['field_' . $field->id] ) ) {
-					$original_option_values = $_POST['field_' . $field->id];
-				}
-
-				$option_values = (array) $original_option_values;
-
-				for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
-
-					// Check for updated posted values, but errors preventing them from being saved first time
-					foreach( $option_values as $i => $option_value ) {
-						if ( isset( $_POST['field_' . $field->id] ) && $_POST['field_' . $field->id] != $option_value ) {
-							if ( !empty( $_POST['field_' . $field->id] ) ) {
-								$option_values[$i] = $_POST['field_' . $field->id];
-							}
-						}
-					}
-
-					$selected = '';
-
-					// Run the allowed option name through the before_save filter, so we'll be sure to get a match
-					$allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
-
-					// First, check to see whether the user-entered value matches
-					if ( in_array( $allowed_options, (array) $option_values ) ) {
-						$selected = ' selected="selected"';
-					}
-
-					// Then, if the user has not provided a value, check for defaults
-					if ( !is_array( $original_option_values ) && empty( $option_values ) && $options[$k]->is_default_option ) {
-						$selected = ' selected="selected"';
-					}
-
-					$html .= apply_filters( 'bp_get_the_profile_field_options_select', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_attr( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $field->id, $selected, $k );
-				}
-				break;
-
-			case 'multiselectbox':
-				$original_option_values = '';
-				$original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $field->id ) );
-
-				if ( empty( $original_option_values ) && !empty( $_POST['field_' . $field->id] ) ) {
-					$original_option_values = $_POST['field_' . $field->id];
-				}
-
-				$option_values = (array) $original_option_values;
-
-				for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
-
-					// Check for updated posted values, but errors preventing them from being saved first time
-					foreach( $option_values as $i => $option_value ) {
-						if ( isset( $_POST['field_' . $field->id] ) && $_POST['field_' . $field->id][$i] != $option_value ) {
-							if ( !empty( $_POST['field_' . $field->id][$i] ) ) {
-								$option_values[] = $_POST['field_' . $field->id][$i];
-							}
-						}
-					}
-					$selected = '';
-
-					// Run the allowed option name through the before_save filter, so we'll be sure to get a match
-					$allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
-
-					// First, check to see whether the user-entered value matches
-					if ( in_array( $allowed_options, (array) $option_values ) ) {
-						$selected = ' selected="selected"';
-					}
-
-					// Then, if the user has not provided a value, check for defaults
-					if ( !is_array( $original_option_values ) && empty( $option_values ) && !empty( $options[$k]->is_default_option ) ) {
-						$selected = ' selected="selected"';
-					}
-
-					$html .= apply_filters( 'bp_get_the_profile_field_options_multiselect', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_attr( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $field->id, $selected, $k );
-				}
-				break;
-
-			case 'radio':
-				$html .= '<div id="field_' . $field->id . '">';
-				$option_value = BP_XProfile_ProfileData::get_value_byid( $field->id );
-
-				for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
-
-					// Check for updated posted values, but errors preventing them from being saved first time
-					if ( isset( $_POST['field_' . $field->id] ) && $option_value != $_POST['field_' . $field->id] ) {
-						if ( !empty( $_POST['field_' . $field->id] ) ) {
-							$option_value = $_POST['field_' . $field->id];
-						}
-					}
-
-					// Run the allowed option name through the before_save
-					// filter, so we'll be sure to get a match
-					$allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
-					$selected        = '';
-
-					// @todo $value is never created
-					if ( $option_value == $allowed_options || !empty( $value ) && $value == $allowed_options || ( empty( $option_value ) && !empty( $options[$k]->is_default_option ) ) )
-						$selected = ' checked="checked"';
-
-					$html .= apply_filters( 'bp_get_the_profile_field_options_radio', '<label><input' . $selected . ' type="radio" name="field_' . $field->id . '" id="option_' . $options[$k]->id . '" value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '"> ' . esc_attr( stripslashes( $options[$k]->name ) ) . '</label>', $options[$k], $field->id, $selected, $k );
-				}
-
-				$html .= '</div>';
-				break;
-
-			case 'checkbox':
-				$option_values = BP_XProfile_ProfileData::get_value_byid( $field->id );
-				$option_values = (array) maybe_unserialize( $option_values );
-
-				// Check for updated posted values, but errors preventing them from being saved first time
-				if ( isset( $_POST['field_' . $field->id] ) && $option_values != maybe_serialize( $_POST['field_' . $field->id] ) ) {
-					if ( !empty( $_POST['field_' . $field->id] ) )
-						$option_values = $_POST['field_' . $field->id];
-				}
-
-				for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
-					$selected = '';
-
-					// First, check to see whether the user's saved values
-					// match the option
-					for ( $j = 0, $count_values = count( $option_values ); $j < $count_values; ++$j ) {
-
-						// Run the allowed option name through the
-						// before_save filter, so we'll be sure to get a match
-						$allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
-
-						// @todo $value is never created
-						if ( $option_values[$j] == $allowed_options || @in_array( $allowed_options, $option_values ) ) {
-							$selected = ' checked="checked"';
-							break;
-						}
-					}
-
-					// If the user has not yet supplied a value for this field,
-					// check to see whether there is a default value available
-					if ( !is_array( $option_values ) && empty( $option_values ) && empty( $selected ) && !empty( $options[$k]->is_default_option ) ) {
-						$selected = ' checked="checked"';
-					}
-
-					$html .= apply_filters( 'bp_get_the_profile_field_options_checkbox', '<label><input' . $selected . ' type="checkbox" name="field_' . $field->id . '[]" id="field_' . $options[$k]->id . '_' . $k . '" value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '"> ' . esc_attr( stripslashes( $options[$k]->name ) ) . '</label>', $options[$k], $field->id, $selected, $k );
-				}
-				break;
-
-			case 'datebox':
-				$date = BP_XProfile_ProfileData::get_value_byid( $field->id );
-
-				// Set day, month, year defaults
-				$day   = '';
-				$month = '';
-				$year  = '';
-
-				if ( !empty( $date ) ) {
-
-					// If Unix timestamp
-					if ( is_numeric( $date ) ) {
-						$day   = date( 'j', $date );
-						$month = date( 'F', $date );
-						$year  = date( 'Y', $date );
-
-					// If MySQL timestamp
-					} else {
-						$day   = mysql2date( 'j', $date );
-						$month = mysql2date( 'F', $date, false ); // Not localized, so that selected() works below
-						$year  = mysql2date( 'Y', $date );
-					}
-				}
-
-				// Check for updated posted values, and errors preventing
-				// them from being saved first time.
-				if ( !empty( $_POST['field_' . $field->id . '_day'] ) ) {
-					if ( $day != $_POST['field_' . $field->id . '_day'] ) {
-						$day = $_POST['field_' . $field->id . '_day'];
-					}
-				}
-
-				if ( !empty( $_POST['field_' . $field->id . '_month'] ) ) {
-					if ( $month != $_POST['field_' . $field->id . '_month'] ) {
-						$month = $_POST['field_' . $field->id . '_month'];
-					}
-				}
-
-				if ( !empty( $_POST['field_' . $field->id . '_year'] ) ) {
-					if ( $year != date( "j", $_POST['field_' . $field->id . '_year'] ) ) {
-						$year = $_POST['field_' . $field->id . '_year'];
-					}
-				}
-
-				// $type will be passed by calling function when needed
-				switch ( $type ) {
-					case 'day':
-						$html .= '<option value=""' . selected( $day, '', false ) . '>--</option>';
-
-						for ( $i = 1; $i < 32; ++$i ) {
-							$html .= '<option value="' . $i .'"' . selected( $day, $i, false ) . '>' . $i . '</option>';
-						}
-						break;
-
-					case 'month':
-						$eng_months = array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' );
-
-						$months = array(
-							__( 'January', 'buddypress' ),
-							__( 'February', 'buddypress' ),
-							__( 'March', 'buddypress' ),
-							__( 'April', 'buddypress' ),
-							__( 'May', 'buddypress' ),
-							__( 'June', 'buddypress' ),
-							__( 'July', 'buddypress' ),
-							__( 'August', 'buddypress' ),
-							__( 'September', 'buddypress' ),
-							__( 'October', 'buddypress' ),
-							__( 'November', 'buddypress' ),
-							__( 'December', 'buddypress' )
-						);
-
-						$html .= '<option value=""' . selected( $month, '', false ) . '>------</option>';
-
-						for ( $i = 0; $i < 12; ++$i ) {
-							$html .= '<option value="' . $eng_months[$i] . '"' . selected( $month, $eng_months[$i], false ) . '>' . $months[$i] . '</option>';
-						}
-						break;
-
-					case 'year':
-						$html .= '<option value=""' . selected( $year, '', false ) . '>----</option>';
-
-						for ( $i = 2037; $i > 1901; $i-- ) {
-							$html .= '<option value="' . $i .'"' . selected( $year, $i, false ) . '>' . $i . '</option>';
-						}
-						break;
-				}
-
-				$html = apply_filters( 'bp_get_the_profile_field_datebox', $html, $type, $day, $month, $year, $field->id, $date );
-
-				break;
-		}
+		ob_start();
+		$field->type_obj->edit_field_options_html( $args );
+		$html = ob_get_contents();
+		ob_end_clean();
 
 		return $html;
 	}
@@ -929,25 +690,128 @@ function bp_edit_profile_button() {
 	) );
 }
 
+/** Visibility ****************************************************************/
+
 /**
  * Echo the field visibility radio buttons
  */
-function bp_profile_visibility_radio_buttons() {
-	echo bp_profile_get_visibility_radio_buttons();
+function bp_profile_visibility_radio_buttons( $args = '' ) {
+	echo bp_profile_get_visibility_radio_buttons( $args );
 }
 	/**
 	 * Return the field visibility radio buttons
 	 */
-	function bp_profile_get_visibility_radio_buttons() {
-		$html = '<ul class="radio">';
+	function bp_profile_get_visibility_radio_buttons( $args = '' ) {
 
-		foreach( bp_xprofile_get_visibility_levels() as $level ) {
-			$checked = $level['id'] == bp_get_the_profile_field_visibility_level() ? ' checked="checked" ' : '';
+		// Parse optional arguments
+		$r = bp_parse_args( $args, array(
+			'field_id'     => bp_get_the_profile_field_id(),
+			'before'       => '<ul class="radio">',
+			'after'        => '</ul>',
+			'before_radio' => '<li>',
+			'after_radio'  => '</li>',
+			'class'        => 'bp-xprofile-visibility'
+		), 'xprofile_visibility_radio_buttons' );
 
-			$html .= '<li><label for="see-field_' . esc_attr( $level['id'] ) . '"><input type="radio" id="see-field_' . esc_attr( $level['id'] ) . '" name="field_' . bp_get_the_profile_field_id() . '_visibility" value="' . esc_attr( $level['id'] ) . '"' . $checked . ' /> ' . esc_html( $level['label'] ) . '</label></li>';
-		}
+		// Empty return value, filled in below if a valid field ID is found
+		$retval = '';
+
+		// Only do-the-do if there's a valid field ID
+		if ( ! empty( $r['field_id'] ) ) :
+
+			// Start the output buffer
+			ob_start();
+
+			// Output anything before
+			echo $r['before']; ?>
+
+			<?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?>
+
+				<?php foreach( bp_xprofile_get_visibility_levels() as $level ) : ?>
+
+					<?php echo $r['before_radio']; ?>
+
+					<label for="<?php esc_attr( 'see-field_' . $r['field_id'] . '_' . $level['id'] ); ?>">
+						<input type="radio" id="<?php echo esc_attr( 'see-field_' . $r['field_id'] . '_' . $level['id'] ); ?>" name="<?php echo esc_attr( 'field_' . $r['field_id'] . '_visibility' ); ?>" value="<?php echo esc_attr( $level['id'] ); ?>" <?php checked( $level['id'], bp_get_the_profile_field_visibility_level() ); ?> />
+						<span class="field-visibility-text"><?php echo esc_html( $level['label'] ); ?></span>
+					</label>
+
+					<?php echo $r['after_radio']; ?>
+
+				<?php endforeach; ?>
+
+			<?php endif;
+
+			// Output anything after
+			echo $r['after'];
+
+			// Get the output buffer and empty it
+			$retval = ob_get_clean();
+		endif;
+
+		return apply_filters( 'bp_profile_get_visibility_radio_buttons', $retval, $r, $args );
+	}
+
+/**
+ * Output the XProfile field visibility select list for settings
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function bp_profile_settings_visibility_select( $args = '' ) {
+	echo bp_profile_get_settings_visibility_select( $args );
+}
+	/**
+	 * Return the XProfile field visibility select list for settings
+	 *
+	 * @since BuddyPress (2.0.0)
+	 */
+	function bp_profile_get_settings_visibility_select( $args = '' ) {
+
+		// Parse optional arguments
+		$r = bp_parse_args( $args, array(
+			'field_id' => bp_get_the_profile_field_id(),
+			'before'   => '',
+			'after'    => '',
+			'class'    => 'bp-xprofile-visibility'
+		), 'xprofile_settings_visibility_select' );
+
+		// Empty return value, filled in below if a valid field ID is found
+		$retval = '';
+
+		// Only do-the-do if there's a valid field ID
+		if ( ! empty( $r['field_id'] ) ) :
+
+			// Start the output buffer
+			ob_start();
+
+			// Output anything before
+			echo $r['before']; ?>
+
+			<?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?>
+
+				<select class="<?php echo esc_attr( $r['class'] ); ?>" name="<?php echo esc_attr( 'field_' . $r['field_id'] ) ; ?>_visibility">
+
+					<?php foreach ( bp_xprofile_get_visibility_levels() as $level ) : ?>
+
+						<option value="<?php echo esc_attr( $level['id'] ); ?>" <?php selected( $level['id'], bp_get_the_profile_field_visibility_level() ); ?>><?php echo esc_html( $level['label'] ); ?></option>
+
+					<?php endforeach; ?>
+
+				</select>
+
+			<?php else : ?>
+
+				<span class="field-visibility-settings-notoggle" title="<?php esc_attr_e( "This field's visibility cannot be changed.", 'buddypress' ); ?>"><?php bp_the_profile_field_visibility_level_label(); ?></span>
+
+			<?php endif;
+
+			// Output anything after
+			echo $r['after'];
 
-		$html .= '</ul>';
+			// Get the output buffer and empty it
+			$retval = ob_get_clean();
+		endif;
 
-		return apply_filters( 'bp_profile_get_visibility_radio_buttons', $html );
+		// Output the dropdown list
+		return apply_filters( 'bp_profile_settings_visibility_select', $retval, $r, $args );
 	}
diff --git a/wp-content/plugins/buddypress/humans.txt b/wp-content/plugins/buddypress/humans.txt
index e801a5bc494e52f43fcddaca462bb952c15ec02f..f9906c8979b0492db0681c4ee489ceb76c8d5324 100644
--- a/wp-content/plugins/buddypress/humans.txt
+++ b/wp-content/plugins/buddypress/humans.txt
@@ -51,9 +51,19 @@ Title: Core Developer
 Twitter: r-a-y
 Favourite Food: tbd
 
+Name: Mathieu Viet
+Title: Core Developer
+Twitter: imath
+Favorite Food: Spaghetti Bolognese
+
+Name: Mercime
+Title: Navigator
+Twitter: mercime_one
+Favorite Food: Paella Valenciana
+
 /* THANKS */
-hnla, mercime, modemlooper, cnorris23, karmatosed, photomatt
+hnla, modemlooper, cnorris23, karmatosed, photomatt
 
 /* META */
-Updated: 2012/10/22
-See: http://humanstxt.org/
\ No newline at end of file
+Updated: 2014/04/14
+See: http://humanstxt.org/
diff --git a/wp-content/plugins/buddypress/readme.txt b/wp-content/plugins/buddypress/readme.txt
index 5f22d07965406ceb5706914ca0552d64672988d2..517f740d4c28469bc0d8adb74680428675bd3206 100644
--- a/wp-content/plugins/buddypress/readme.txt
+++ b/wp-content/plugins/buddypress/readme.txt
@@ -1,13 +1,13 @@
-=== Plugin Name ===
+=== BuddyPress ===
 Contributors: johnjamesjacoby, DJPaul, boonebgorges, r-a-y
 Tags: social networking, activity, profiles, messaging, friends, groups, forums, notifications, settings, twitter, facebook, social, community, networks, networking, cms
-Requires at least: 3.5
-Tested up to: 3.6
-Stable tag: 1.8.1
+Requires at least: 3.6
+Tested up to: 3.9
+Stable tag: 2.0
 License: GPLv2 or later
 License URI: http://www.gnu.org/licenses/gpl-2.0.html
 
-Social networking in a box. Build a social network for your company, school, sports team or niche community.
+Social networking in a box. Build a social network for your company, school, sports team, or niche community.
 
 == Description ==
 
@@ -29,11 +29,11 @@ Visit the <a href="http://buddypress.org/">BuddyPress website</a> for more infor
 
 You can download and install BuddyPress using the built in WordPress plugin installer. If you download BuddyPress manually, make sure it is uploaded to "/wp-content/plugins/buddypress/".
 
-Activate BuddyPress in the "Plugins" admin panel using the "Activate" link. You'll then see a message asking you to complete the BuddyPress Installation Wizard, which will guide you through configuring your site for BuddyPress.
+Activate BuddyPress in the "Plugins" admin panel using the "Activate" link. If you're using WordPress Multisite, you can optionally activate BuddyPress Network Wide, allowing its toolbar integration to appear on all of your sites, and optionally turning on post and comment aggregation to the Activity Stream too!
 
---- Discussion Forums ---
+= Discussion Forums =
 
-BuddyPress includes full support for discussion forums. Each group created on your site can have its own forum. If you'd like to enable this feature, after completing the Installation Wizard, visit the "Forums Setup" item under the "BuddyPress" menu in your WordPress admin-area, and follow the on-screen instructions.
+Try <a href="http://wordpress.org/plugins/bbpress/">bbPress</a>. It's designed to work cohesively with BuddyPress Groups, Profiles, and Notifications. Each group on your site can choose to have its own forum, and each user's topics, replies, favorites, and subscriptions appear in their profiles.
 
 == Frequently Asked Questions ==
 
@@ -63,11 +63,11 @@ Check out the development trunk of BuddyPress via Subversion, from <a href="http
 
 == Screenshots ==
 
-1. **Activity Streams** - Global, personal and group activity streams with threaded commenting, direct posting, favoriting and @mentions. All with full RSS feeds and email notification support.
+1. **Activity Streams** - Global, personal, and group activity streams with threaded commenting, direct posting, favoriting and @mentions. All with full RSS feeds and email notification support.
 2. **Extended Profiles** - Fully editable profile fields allow you to define the fields users can fill in to describe themselves. Tailor profile fields to suit your audience.
 3. **User Settings** - Give your users complete control over profile and notification settings. Settings are fully integrated into your theme, and can be disabled by the administrator.
 4. **Extensible Groups** - Powerful public, private or hidden groups allow your users to break the discussion down into specific topics. Extend groups with your own custom features using the group extension API.
-5. **Friend Connections** - Let your users make connections so they can track the activity of others, or filter on only those users they care about the most.
+5. **Friend Connections** - Let your users make connections so they can track the activity of others, or filter to show only those users they care about the most.
 6. **Private Messaging** - Private messaging will allow your users to talk to each other directly and in private. Not just limited to one-on-one discussions, your users can send messages to multiple recipients.
 7. **Blogging Network** - Allow your users to start their own blogs using WordPress's Multisite feature, and track posts and comments from across your blog network in the activity stream.
 
@@ -77,6 +77,18 @@ BuddyPress is available in more than 20 languages. For more information, check o
 
 == Upgrade Notice ==
 
+= 2.0 =
+See: http://codex.buddypress.org/releases/version-2-0/
+
+= 1.9.2 =
+See: http://codex.buddypress.org/releases/version-1-9-2/
+
+= 1.9.1 =
+See: http://codex.buddypress.org/releases/version-1-9-1/
+
+= 1.9 =
+See: http://codex.buddypress.org/releases/version-1-9/
+
 = 1.8.1 =
 See: http://codex.buddypress.org/releases/version-1-8-1/
 
@@ -127,6 +139,9 @@ Fixes over 10 bugs.
 
 == Changelog ==
 
+= 1.9 =
+See: http://codex.buddypress.org/releases/version-1-9/
+
 = 1.8.1 =
 See: http://codex.buddypress.org/releases/version-1-8-1/