Index: plugin.php
===================================================================
--- plugin.php	(revision 5825)
+++ plugin.php	(working copy)
@@ -15,11 +15,14 @@
  * @param int $accepted_args optional. The number of arguments the function accept (default 1). In WordPress 1.5.1+, hooked functions can take extra arguments that are set when the matching do_action() or apply_filters() call is run.
  * @return boolean true if the <tt>$function_to_add</tt> is added succesfully to filter <tt>$tag</tt>. How many arguments your function takes. In WordPress 1.5.1+, hooked functions can take extra arguments that are set when the matching <tt>do_action()</tt> or <tt>apply_filters()</tt> call is run. For example, the action <tt>comment_id_not_found</tt> will pass any functions that hook onto it the ID of the requested comment.
  */
-function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
+function add_filter($tag, &$function_to_add, $priority = 10, $accepted_args = 1) {
 	global $wp_filter, $merged_filters;
 
 	// So the format is wp_filter['tag']['array of priorities']['array of functions serialized']['array of ['array (functions, accepted_args)]']
-	$wp_filter[$tag][$priority][serialize($function_to_add)] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
+	$fn_idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
+	
+	$wp_filter[$tag][$priority][$fn_idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
+	//$wp_filter[$tag][$priority][serialize($function_to_add)] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
 	unset( $merged_filters[ $tag ] );
 	return true;
 }
@@ -97,7 +100,7 @@
  * @return boolean Whether the function is removed.
  */
 function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
-	$function_to_remove = serialize($function_to_remove);
+	$function_to_remove = _wp_filter_build_unique_id($tag, &$function_to_remove, $priority);
 
 	$r = isset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]);
 
@@ -280,4 +283,51 @@
 	add_action('deactivate_' . $file, $function);
 }
 
+function _wp_filter_build_unique_id($tag, &$function_to_add, $priority = 10)
+{
+	global $wp_filter;
+	// If function then just skip all of the tests and not overwrite the following.
+	$fn_idx = $function_to_add;
+	
+	// Only test if using an array to call a class and method.
+	// Else bypass all of the following checks.
+	if(is_array($function_to_add)) 
+	{
+		list($obj,$fn) = $function_to_add;
+		
+		// Expect most use cases for $obj to be objects and not strings
+		if(is_object($obj))
+		{
+			// We are going to use $classname more than once, store it
+			$classname = get_class($obj);
+			$fn_idx = $classname.$fn;
+			
+			if(!is_null($function_to_add[0]->wp_filter_id))
+			{
+				$fn_idx .= $function_to_add[0]->wp_filter_id;
+			}
+			
+			// Compare the two object references to see if they are the same object.
+			// This is slow however as it will check each property and method for similar, much
+			// like an array comparsion. Should work similar to PHP 4 and PHP 5.
+			if($function_to_add[0] == $wp_filter[$tag][$priority][$fn_idx]['function'][0]) {
+				return $fn_idx; // Do not add
+			} else {
+				$i = count($wp_filter[$tag][$priority]);
+				$function_to_add[0]->wp_filter_id = $i;
+				$fn_idx .= $function_to_add[0]->wp_filter_id;
+			}
+		}
+		// Must mean that it is using static calling.
+		// We can also assume that if they are using static calling
+		// it doesn't matter if they have two or more variables that they are trying
+		// to add to the same hooks. The bug would be theirs, we can only assume
+		// that they know enough when doing static method call binding to know what
+		// to expect.
+		else 
+			$fn_idx = $obj.fn;
+	}
+	return $fn_idx;
+}
+
 ?>

