Index: bp-forums/bp-forums-functions.php
===================================================================
--- bp-forums/bp-forums-functions.php	(revision 4624)
+++ bp-forums/bp-forums-functions.php	(working copy)
@@ -80,6 +80,8 @@ function bp_forums_get_forum_topics( $args = '' ) {
 		'user_id'       => false,
 		'page'          => 1,
 		'per_page'      => 15,
+		'offset'	=> false,
+		'number'	=> false,
 		'exclude'       => false,
 		'show_stickies' => 'all',
 		'filter'        => false // if $type = tag then filter is the tag name, otherwise it's terms to search on.
@@ -91,7 +93,7 @@ function bp_forums_get_forum_topics( $args = '' ) {
 	if ( class_exists( 'BB_Query' ) ) {
 		switch ( $type ) {
 			case 'newest':
-				$query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'topic_author_id' => $user_id, 'per_page' => $per_page, 'page' => $page, 'number' => $per_page, 'exclude' => $exclude, 'topic_title' => $filter, 'sticky' => $show_stickies ), 'get_latest_topics' );
+				$query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'topic_author_id' => $user_id, 'per_page' => $per_page, 'page' => $page, 'number' => $per_page, 'exclude' => $exclude, 'topic_title' => $filter, 'sticky' => $show_stickies, 'offset' => $offset, 'number' => $number ), 'get_latest_topics' );
 				$topics =& $query->results;
 				break;
 
Index: bp-forums/bp-forums-template.php
===================================================================
--- bp-forums/bp-forums-template.php	(revision 4624)
+++ bp-forums/bp-forums-template.php	(working copy)
@@ -68,22 +68,24 @@ class BP_Forums_Template_Forum {
 	var $sort_by;
 	var $order;
 
-	function BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms ) {
-		$this->__construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms );
+	function BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms, $offset = false, $number = false ) {
+		$this->__construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms, $offset, $number );
 	}
 
-	function __construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms ) {	
+	function __construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms, $offset = false, $number = false ) {	
 		global $bp;
 
-		$this->pag_page     = isset( $_REQUEST['p'] ) ? intval( $_REQUEST['p'] ) : $page;
-		$this->pag_num      = isset( $_REQUEST['n'] ) ? intval( $_REQUEST['n'] ) : $per_page;
+		$this->pag_page     = $page;
+		$this->pag_num      = $per_page;
 		$this->type         = $type;
 		$this->search_terms = $search_terms;
 		$this->forum_id     = $forum_id;
+		$this->offset	    = $offset;
+		$this->number	    = $number;
 
 		switch ( $type ) {
-			case 'newest': default:
-				$this->topics = bp_forums_get_forum_topics( array( 'user_id' => $user_id, 'forum_id' => $forum_id, 'filter' => $search_terms, 'page' => $this->pag_page, 'per_page' => $this->pag_num, 'show_stickies' => $no_stickies ) );
+			case 'newest': default:				
+				$this->topics = bp_forums_get_forum_topics( array( 'user_id' => $user_id, 'forum_id' => $forum_id, 'filter' => $search_terms, 'page' => $this->pag_page, 'per_page' => $this->pag_num, 'show_stickies' => $no_stickies, 'offset' => $offset, 'number' => $number ) );
 				break;
 
 			case 'popular':
@@ -111,7 +113,9 @@ class BP_Forums_Template_Forum {
 			} else if ( !empty( $bp->groups->current_group ) ) {
 				$topic_count = (int)groups_total_public_forum_topic_count( $type );
 			} else {
-				$topic_count = count( $this->topics );
+				// For forum directories, get a true count
+				$status = is_super_admin() ? 'all' : 'public'; // todo: member-of
+				$topic_count = (int)groups_total_forum_topic_count( $status );
 			}
 
 			if ( !$max || $max >= $topic_count ) {
@@ -119,7 +123,7 @@ class BP_Forums_Template_Forum {
 			} else {
 				$this->total_topic_count = (int)$max;
 			}
-
+			
 			if ( $max ) {
 				if ( $max >= count($this->topics) ) {
 					$this->topic_count = count( $this->topics );
@@ -134,22 +138,6 @@ class BP_Forums_Template_Forum {
 		$this->topic_count       = apply_filters_ref_array( 'bp_forums_template_topic_count',                                 array( $this->topic_count, &$this->topics, $type, $forum_id, $per_page, $max, $no_stickies ) );
 		$this->total_topic_count = apply_filters_ref_array( 'bp_forums_template_total_topic_count', array( $this->total_topic_count, $this->topic_count, &$this->topics, $type, $forum_id, $per_page, $max, $no_stickies ) );
 
-		if ( !$no_stickies ) {
-			$stickies = array();
-			$standard = array();
-
-			// Place stickies at the top - not sure why bbPress doesn't do this?
-			foreach( (array)$this->topics as $topic ) {
-				if ( isset( $topic->topic_sticky ) && 1 == (int)$topic->topic_sticky ) {
-					$stickies[] = $topic;
-				} else {
-					$standard[] = $topic;
-				}
-			}
-
-			$this->topics = array_merge( (array)$stickies, (array)$standard );
-		}
-
 		// Fetch extra information for topics, so we don't have to query inside the loop
 		$this->topics = bp_forums_get_topic_extras( $this->topics );
 
@@ -224,7 +212,6 @@ function bp_has_forum_topics( $args = '' ) {
 	$user_id      = 0;
 	$forum_id     = false;
 	$search_terms = false;
-	$no_stickies  = 'all';
 
 	// User filtering
 	if ( !empty( $bp->displayed_user->id ) )
@@ -254,19 +241,20 @@ function bp_has_forum_topics( $args = '' ) {
 	// If $_GET['fs'] is set, let's auto populate the search_terms var
 	if ( bp_is_directory() && !empty( $_GET['fs'] ) )
 		$search_terms = $_GET['fs'];
-
-	// Show stickies on a group forum
-	if ( isset( $bp->groups->current_group ) )
-		$no_stickies = null;
+	
+	// Get the pagination arguments from $_REQUEST
+	$page     = isset( $_REQUEST['p'] ) ? intval( $_REQUEST['p'] ) : 1;
+	$per_page = isset( $_REQUEST['n'] ) ? intval( $_REQUEST['n'] ) : 20;
 
 	$defaults = array(
 		'type'         => $type,
 		'forum_id'     => $forum_id,
 		'user_id'      => $user_id,
-		'page'         => 1,
-		'per_page'     => 20,
+		'page'         => $page,
+		'per_page'     => $per_page,
 		'max'          => false,
-		'no_stickies'  => $no_stickies,
+		'number'       => false,
+		'offset'       => false,
 		'search_terms' => $search_terms
 	);
 
@@ -279,8 +267,91 @@ function bp_has_forum_topics( $args = '' ) {
 		$search_terms = $bp->action_variables[0];
 		$type = 'tags';
 	}
-
-	$forum_template = new BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms );
+	
+	// Fetch the stickies
+	$stickies_template = new BP_Forums_Template_Forum( $type, $forum_id, $user_id, 0, 0, $max, 'sticky', $search_terms );
+	
+	// If stickies are found, try merging them
+	if ( $stickies_template->has_topics() ) {
+	
+		// If stickies are for current $page		
+		$page_start_num = ( ( $page - 1 ) * $per_page ) + 1;
+		$page_end_num 	= $page * $per_page <= $stickies_template->total_topic_count ? $page * $per_page : $stickies_template->total_topic_count;
+		
+		// Calculate the number of sticky topics that will be shown on this page
+		if ( $stickies_template->topic_count < $page_start_num ) {
+			$this_page_stickies = 0;
+		} else {			
+			$this_page_stickies = $stickies_template->topic_count - $per_page * floor( $stickies_template->topic_count / $per_page ) * ( $page - 1 ); // Total stickies minus sticky count through this page
+			
+			// $this_page_stickies cannot be more than $per_page or less than 0
+			if ( $this_page_stickies > $per_page )
+				$this_page_stickies = $per_page;
+			else if ( $this_page_stickies < 0 )
+				$this_page_stickies = 0;
+		}
+		
+		// Calculate the total number of topics that will be shown on this page
+		$this_page_topics = $stickies_template->total_topic_count >= ( $page * $per_page ) ? $per_page : $page_end_num - ( $page_start_num - 1 );
+		
+		// If the number of stickies to be shown is less than $per_page, fetch some non-
+		// stickies to fill in the rest
+		if ( $this_page_stickies < $this_page_topics ) {
+			// How many non-stickies do we need?
+			$non_sticky_number = $this_page_topics - $this_page_stickies;
+			
+			// Calculate the non-sticky offset			
+			// How many non-stickies on all pages up to this point?
+			$non_sticky_total = $page_end_num - $stickies_template->topic_count;
+			
+			// The offset is the number of total non-stickies, less the number to be
+			// shown on this page
+			$non_sticky_offset = $non_sticky_total - $non_sticky_number;
+			
+			// Fetch the non-stickies
+			$forum_template = new BP_Forums_Template_Forum( $type, $forum_id, $user_id, 1, $per_page, $max, 'no', $search_terms, $non_sticky_offset, $non_sticky_number );
+			
+			// If there are stickies to merge on this page, do it now
+			if ( $this_page_stickies ) {
+				// Correct the topic_count
+				$forum_template->topic_count += (int)$this_page_stickies;
+				
+				// Figure out which stickies need to be included
+				$this_page_sticky_topics = array_slice( $stickies_template->topics, 0 - $this_page_stickies );
+				
+				// Merge these topics into the forum template
+				$forum_template->topics = array_merge( $this_page_sticky_topics, (array)$forum_template->topics );
+			}
+		} else {
+			// This page has no non-stickies
+			$forum_template = $stickies_template;
+			
+			// Adjust the topic count and trim the topics
+			$forum_template->topic_count = $this_page_stickies;
+			$forum_template->topics      = array_slice( $forum_template->topics, $page - 1 );		
+			
+		}
+				
+		// Because we're using a manual offset and number for the topic query, we
+		// must set the page number manually, and recalculate the pagination links
+		$forum_template->pag_num     = $per_page;
+		$forum_template->pag_page    = $page;
+		
+		$forum_template->pag_links = paginate_links( array(
+			'base'      => add_query_arg( array( 'p' => '%#%', 'n' => $forum_template->pag_num ) ),
+			'format'    => '',
+			'total'     => ceil( (int)$forum_template->total_topic_count / (int)$forum_template->pag_num ),
+			'current'   => $forum_template->pag_page,
+			'prev_text' => '&larr;',
+			'next_text' => '&rarr;',
+			'mid_size'  => 1
+		) );
+		
+	} else {
+		// Fetch the non-sticky topics if no stickies were found
+		$forum_template = new BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, 'all', $search_terms );
+	}
+		
 	return apply_filters( 'bp_has_topics', $forum_template->has_topics(), $forum_template );
 }
 
@@ -1280,4 +1351,4 @@ function bp_forum_topic_count( $user_id = 0 ) {
 	function bp_get_forum_topic_count( $user_id = 0 ) {
 		return apply_filters( 'bp_get_forum_topic_count', bp_forums_total_topic_count( $user_id ) );
 	}
-?>
\ No newline at end of file
+?>
Index: bp-groups/bp-groups-classes.php
===================================================================
--- bp-groups/bp-groups-classes.php	(revision 4624)
+++ bp-groups/bp-groups-classes.php	(working copy)
@@ -595,6 +595,41 @@ Class BP_Groups_Group {
 
 		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 ) );
 	}
+	
+	
+	/**
+	 * Get a total count of all topics of a given status, across groups/forums
+	 *
+	 * @package BuddyPress
+	 * @since 1.3
+	 *
+	 * @param str $status 'public', 'private', 'hidden', 'all' Which group types to count
+	 * @return int The topic count
+	 */
+	function get_global_topic_count( $status = 'public' ) {
+		global $bbdb, $wpdb, $bp;
+		
+		switch ( $status ) {
+			case 'all' :
+				$status_sql = '';
+				break;
+				
+			case 'hidden' :
+				$status_sql = $wpdb->prepare( "AND g.status = 'hidden'" );
+				break;
+				
+			case 'private' :
+				$status_sql = $wpdb->prepare( "AND g.status = 'private'" );
+				break;
+				
+			case 'public' :
+			default :
+				$status_sql = $wpdb->prepare( "AND g.status = 'public'" );
+				break;
+		}
+		
+		return $wpdb->get_var( "SELECT COUNT(t.topic_id) FROM {$bbdb->topics} AS t INNER JOIN {$bp->groups->table_name_groupmeta} AS gm ON t.forum_id = gm.meta_value INNER JOIN {$bp->groups->table_name} AS g ON gm.group_id = g.id WHERE gm.meta_key = 'forum_id' {$status_sql} AND t.topic_status = '0' AND t.topic_sticky != '2' " );
+	}
 }
 
 Class BP_Groups_Member {
Index: bp-groups/bp-groups-forums.php
===================================================================
--- bp-groups/bp-groups-forums.php	(revision 4624)
+++ bp-groups/bp-groups-forums.php	(working copy)
@@ -244,9 +244,21 @@ function groups_delete_group_forum_post( $post_id, $topic_id ) {
 	return false;
 }
 
-
 function groups_total_public_forum_topic_count( $type = 'newest' ) {
 	return apply_filters( 'groups_total_public_forum_topic_count', BP_Groups_Group::get_global_forum_topic_count( $type ) );
 }
 
+/**
+ * Get a total count of all topics of a given status, across groups/forums
+ *
+ * @package BuddyPress
+ * @since 1.3
+ *
+ * @param str $status 'public', 'private', 'hidden', 'all' Which group types to count
+ * @return int The topic count
+ */
+function groups_total_forum_topic_count( $status = 'public' ) {
+	return apply_filters( 'groups_total_forum_topic_count', BP_Groups_Group::get_global_topic_count( $status ) );
+}
+
 ?>
