Index: wp-includes/plugin.php
===================================================================
--- wp-includes/plugin.php	(revision 15570)
+++ wp-includes/plugin.php	(working copy)
@@ -132,45 +132,9 @@
  * @return mixed The filtered value after all hooked functions are applied to it.
  */
 function apply_filters($tag, $value) {
-	global $wp_filter, $merged_filters, $wp_current_filter;
-
-	$args = array();
-	$wp_current_filter[] = $tag;
-
-	// Do 'all' actions first
-	if ( isset($wp_filter['all']) ) {
-		$args = func_get_args();
-		_wp_call_all_hook($args);
-	}
-
-	if ( !isset($wp_filter[$tag]) ) {
-		array_pop($wp_current_filter);
-		return $value;
-	}
-
-	// Sort
-	if ( !isset( $merged_filters[ $tag ] ) ) {
-		ksort($wp_filter[$tag]);
-		$merged_filters[ $tag ] = true;
-	}
-
-	reset( $wp_filter[ $tag ] );
-
-	if ( empty($args) )
-		$args = func_get_args();
-
-	do {
-		foreach( (array) current($wp_filter[$tag]) as $the_ )
-			if ( !is_null($the_['function']) ){
-				$args[1] = $value;
-				$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
-			}
-
-	} while ( next($wp_filter[$tag]) !== false );
-
-	array_pop( $wp_current_filter );
-
-	return $value;
+	$args = func_get_args();
+	$tag  = array_shift( $args );
+	return _wp_call_hook(true, $tag, $args);
 }
 
 /**
@@ -191,39 +155,7 @@
  * @return mixed The filtered value after all hooked functions are applied to it.
  */
 function apply_filters_ref_array($tag, $args) {
-	global $wp_filter, $merged_filters, $wp_current_filter;
-
-	$wp_current_filter[] = $tag;
-
-	// Do 'all' actions first
-	if ( isset($wp_filter['all']) ) {
-		$all_args = func_get_args();
-		_wp_call_all_hook($all_args);
-	}
-
-	if ( !isset($wp_filter[$tag]) ) {
-		array_pop($wp_current_filter);
-		return $args[0];
-	}
-
-	// Sort
-	if ( !isset( $merged_filters[ $tag ] ) ) {
-		ksort($wp_filter[$tag]);
-		$merged_filters[ $tag ] = true;
-	}
-
-	reset( $wp_filter[ $tag ] );
-
-	do {
-		foreach( (array) current($wp_filter[$tag]) as $the_ )
-			if ( !is_null($the_['function']) )
-				$args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
-
-	} while ( next($wp_filter[$tag]) !== false );
-
-	array_pop( $wp_current_filter );
-
-	return $args[0];
+	return _wp_call_hook( true, $tag, $args );
 }
 
 /**
@@ -350,53 +282,9 @@
  * @return null Will return null if $tag does not exist in $wp_filter array
  */
 function do_action($tag, $arg = '') {
-	global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;
-
-	if ( ! isset($wp_actions) )
-		$wp_actions = array();
-
-	if ( ! isset($wp_actions[$tag]) )
-		$wp_actions[$tag] = 1;
-	else
-		++$wp_actions[$tag];
-
-	$wp_current_filter[] = $tag;
-
-	// Do 'all' actions first
-	if ( isset($wp_filter['all']) ) {
-		$all_args = func_get_args();
-		_wp_call_all_hook($all_args);
-	}
-
-	if ( !isset($wp_filter[$tag]) ) {
-		array_pop($wp_current_filter);
-		return;
-	}
-
-	$args = array();
-	if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
-		$args[] =& $arg[0];
-	else
-		$args[] = $arg;
-	for ( $a = 2; $a < func_num_args(); $a++ )
-		$args[] = func_get_arg($a);
-
-	// Sort
-	if ( !isset( $merged_filters[ $tag ] ) ) {
-		ksort($wp_filter[$tag]);
-		$merged_filters[ $tag ] = true;
-	}
-
-	reset( $wp_filter[ $tag ] );
-
-	do {
-		foreach ( (array) current($wp_filter[$tag]) as $the_ )
-			if ( !is_null($the_['function']) )
-				call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
-
-	} while ( next($wp_filter[$tag]) !== false );
-
-	array_pop($wp_current_filter);
+	$args = func_get_args();
+	$tag  = array_shift( $args );
+	_wp_call_hook(false, $tag, $args);
 }
 
 /**
@@ -436,45 +324,7 @@
  * @return null Will return null if $tag does not exist in $wp_filter array
  */
 function do_action_ref_array($tag, $args) {
-	global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;
-
-	if ( ! isset($wp_actions) )
-		$wp_actions = array();
-
-	if ( ! isset($wp_actions[$tag]) )
-		$wp_actions[$tag] = 1;
-	else
-		++$wp_actions[$tag];
-
-	$wp_current_filter[] = $tag;
-
-	// Do 'all' actions first
-	if ( isset($wp_filter['all']) ) {
-		$all_args = func_get_args();
-		_wp_call_all_hook($all_args);
-	}
-
-	if ( !isset($wp_filter[$tag]) ) {
-		array_pop($wp_current_filter);
-		return;
-	}
-
-	// Sort
-	if ( !isset( $merged_filters[ $tag ] ) ) {
-		ksort($wp_filter[$tag]);
-		$merged_filters[ $tag ] = true;
-	}
-
-	reset( $wp_filter[ $tag ] );
-
-	do {
-		foreach( (array) current($wp_filter[$tag]) as $the_ )
-			if ( !is_null($the_['function']) )
-				call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
-
-	} while ( next($wp_filter[$tag]) !== false );
-
-	array_pop($wp_current_filter);
+	_wp_call_hook( false, $tag, $args );
 }
 
 /**
@@ -701,6 +551,50 @@
 }
 
 /**
+ * Call a hook
+ * 
+ * @since 3.1
+ * @access private
+ * @param bool   $filter True: apply_filter, False: do_action 
+ * @param string $tag The name of the filter hook.
+ * @param array  $args The arguments supplied to the functions hooked on <tt>$tag</tt>
+ * @return mixed first element of $args, filtered if applicable
+ */
+function _wp_call_hook($filter, $tag, $args) {
+	global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;
+	
+	$filter || isset( $wp_actions[$tag] ) && $wp_actions[$tag]++ || $wp_actions[$tag] = 1;
+
+	$wp_current_filter[] = $tag; // hook stack
+
+	// Do 'all' actions first
+	isset( $wp_filter['all'] ) && _wp_call_all_hook( array_merge( array($tag), $args ) );
+
+	if ( isset( $wp_filter[$tag] ) ) {
+		// Sort
+		isset( $merged_filters[$tag] ) || $merged_filters[$tag] = ksort( $wp_filter[$tag] );
+
+		for ( $go = reset( $wp_filter[$tag] ); false !== $go ; $go = next( $wp_filter[$tag] ) ) {
+			foreach( (array) current( $wp_filter[$tag] ) as $the_ ) {
+				if ( is_null( $the_['function'] ) )
+					continue; 
+				
+				$callback  = $the_['function'];
+				$count     = max( 0, (int) $the_['accepted_args'] );
+				$parameter = array_slice( $args, 0, $count );
+
+				$filter
+				? $args[0] = call_user_func_array( $callback, $parameter) 
+				: call_user_func_array( $callback, $parameter);
+			}
+		}
+	}
+
+	array_pop( $wp_current_filter ); // hook stack
+	return isset( $args[0] ) ? $args[0] : null;
+}
+
+/**
  * Build Unique ID for storage and retrieval.
  *
  * The old way to serialize the callback caused issues and this function is the
