diff -ur xdebug-2.0.0RC1/xdebug.c xdebug-2.0.0RC1.new/xdebug.c
--- xdebug-2.0.0RC1/xdebug.c	2006-10-08 16:54:14.000000000 -0400
+++ xdebug-2.0.0RC1.new/xdebug.c	2006-10-27 00:57:30.000000000 -0400
@@ -976,8 +976,8 @@
 			if (
 				(strcmp(tmpf->common.function_name, "call_user_func") == 0) ||
 				(strcmp(tmpf->common.function_name, "call_user_func_array") == 0) ||
-				(strcmp(tmpf->common.function_name, "call_user_func_method") == 0) ||
-				(strcmp(tmpf->common.function_name, "call_user_func_method_array") == 0)
+				(strcmp(tmpf->common.function_name, "call_user_method") == 0) ||
+				(strcmp(tmpf->common.function_name, "call_user_method_array") == 0)
 			) {
 				tmp->filename = xdstrdup(((function_stack_entry*) XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))))->filename);
 			}
diff -ur xdebug-2.0.0RC1/xdebug_profiler.c xdebug-2.0.0RC1.new/xdebug_profiler.c
--- xdebug-2.0.0RC1/xdebug_profiler.c	2006-10-08 16:54:15.000000000 -0400
+++ xdebug-2.0.0RC1.new/xdebug_profiler.c	2006-10-27 17:05:22.000000000 -0400
@@ -146,33 +146,62 @@
 #endif
 }
 
+static int xdebug_profiler_skip_p(function_stack_entry* fse) {
+	return fse->prev && fse->function.function &&
+		(!strcmp(fse->function.function, "call_user_func") ||
+		 !strcmp(fse->function.function, "call_user_func_array") ||
+		 !strcmp(fse->function.function, "call_user_method") ||
+		 !strcmp(fse->function.function, "call_without_strict") ||
+		 !strcmp(fse->function.function, "call_user_method_array") ||
+		 (fse->function.class &&
+		  !strcmp(fse->function.class, "Packages") &&
+		  !strcmp(fse->function.function, "need")));
+}
+
+static char* xdebug_profiler_fse_name(function_stack_entry* fse, int* default_lineno TSRMLS_DC) {
+	char *tmp_fname, *tmp_name;
+	
+	tmp_name = show_fname(fse->function, 0, 0 TSRMLS_CC);
+	switch (fse->function.type) {
+	case XFUNC_INCLUDE:
+	case XFUNC_INCLUDE_ONCE:
+	case XFUNC_REQUIRE:
+	case XFUNC_REQUIRE_ONCE:
+		tmp_fname = xdebug_sprintf("%s::%s", tmp_name, fse->include_filename);
+		xdfree(tmp_name);
+		tmp_name = tmp_fname;
+		if(default_lineno) {
+			*default_lineno = 1;
+		}
+		
+		break;
+		
+	default:
+		if(default_lineno) {
+			*default_lineno = fse->lineno;
+		}
+		
+		break;
+	}
+	
+	return tmp_name;
+}
+
 
 void xdebug_profiler_function_user_end(function_stack_entry *fse, zend_op_array* op_array TSRMLS_DC)
 {
 	xdebug_llist_element *le;
-	char                 *tmp_fname, *tmp_name;
+	char                 *tmp_name;
 	int                   default_lineno = 0;
+	xdebug_call_entry    *ce = NULL;
 
 	xdebug_profiler_function_push(fse);
-	tmp_name = show_fname(fse->function, 0, 0 TSRMLS_CC);
-	switch (fse->function.type) {
-		case XFUNC_INCLUDE:
-		case XFUNC_INCLUDE_ONCE:
-		case XFUNC_REQUIRE:
-		case XFUNC_REQUIRE_ONCE:
-			tmp_fname = xdebug_sprintf("%s::%s", tmp_name, fse->include_filename);
-			xdfree(tmp_name);
-			tmp_name = tmp_fname;
-			default_lineno = 1;
-			break;
-
-		default:
-			default_lineno = fse->lineno;
-			break;
-	}
-
+	
+	tmp_name = xdebug_profiler_fse_name(fse, &default_lineno);
+	//fprintf(stderr, "End of function '%s'\n", tmp_name);
+	
 	if (fse->prev) {
-		xdebug_call_entry *ce = xdmalloc(sizeof(xdebug_call_entry));
+		ce = xdmalloc(sizeof(xdebug_call_entry));
 		ce->filename = xdstrdup(fse->filename);
 		ce->function = xdstrdup(tmp_name);
 		ce->time_taken = fse->profile.time;
@@ -181,10 +210,10 @@
 #if HAVE_PHP_MEMORY_USAGE
 		ce->mem_used = fse->profile.memory - XG_MEMORY_USAGE();
 #endif
-
+		
 		xdebug_llist_insert_next(fse->prev->profile.call_list, NULL, ce);
 	}
-
+	
 	if (op_array) {
 		fprintf(XG(profile_file), "fl=%s\n", op_array->filename);
 	} else {
@@ -195,8 +224,7 @@
 	} else {
 		fprintf(XG(profile_file), "fn=php::%s\n", tmp_name);
 	}
-	xdfree(tmp_name);
-
+	
 	if (fse->function.function && strcmp(fse->function.function, "{main}") == 0) {
 #if HAVE_PHP_MEMORY_USAGE
 		fprintf(XG(profile_file), "\nsummary: %lu %u\n\n", (unsigned long) (fse->profile.time * 10000000), XG_MEMORY_USAGE());
@@ -205,47 +233,94 @@
 #endif
 	}
 	fflush(XG(profile_file));
-
-	/* update aggregate data */
-	if (XG(profiler_aggregate)) {
-		fse->aggr_entry->time_inclusive += fse->profile.time;
-		fse->aggr_entry->call_count++;
-	}
-
+	
+	double net_time_taken = fse->profile.time;
+	
+#ifdef HAVE_PHP_MEMORY_USAGE
+	long net_mem_used = fse->memory;
+#endif
+	
 	/* Subtract time in calledfunction from time here */
 	for (le = XDEBUG_LLIST_HEAD(fse->profile.call_list); le != NULL; le = XDEBUG_LLIST_NEXT(le))
 	{
 		xdebug_call_entry *call_entry = XDEBUG_LLIST_VALP(le);
-		fse->profile.time -= call_entry->time_taken;
+		net_time_taken -= call_entry->time_taken;
 #if HAVE_PHP_MEMORY_USAGE
-		fse->memory -= call_entry->mem_used;
+		net_mem_used -= call_entry->mem_used;
 #endif
 	}
+
+	/* Reassign children of this node to our parent if we've marked it as "skip" */
+	if (xdebug_profiler_skip_p(fse)) {
+		
+		/* update aggregate data with net data */
+		if (XG(profiler_aggregate)) {
+			fse->aggr_entry->time_inclusive += net_time_taken;
+			fse->aggr_entry->call_count++;
+		}
+			
+		/* xdebug_profiler_skip_p(fse) implies fse->prev, which
+		 * implies that ce is valid */
+		ce->time_taken = net_time_taken;
+		
 #if HAVE_PHP_MEMORY_USAGE
-	fprintf(XG(profile_file), "%d %lu %ld\n", default_lineno, (unsigned long) (fse->profile.time * 10000000), (XG_MEMORY_USAGE() - fse->profile.memory) < 0 ? 0 : (XG_MEMORY_USAGE() - fse->profile.memory));
+		ce->mem_used = net_mem_used;
+#endif
+		
+		/* Move the call list to the parent call list; if
+		 * xdebug_profile_p is true, we know there is a parent */
+		char* prevname = xdebug_profiler_fse_name(fse->prev, NULL);
+		
+		for(le = XDEBUG_LLIST_HEAD(fse->profile.call_list); le != NULL; le = XDEBUG_LLIST_NEXT(le))
+		{
+			xdebug_call_entry *ce1 = XDEBUG_LLIST_VALP(le);
+			xdebug_call_entry *ce2 = xdmalloc(sizeof(xdebug_call_entry));
+			memcpy(ce2, ce1, sizeof(xdebug_call_entry));
+			ce2->filename = ce1->filename ? xdstrdup(ce1->filename) : NULL;
+			ce2->function = ce1->function ? xdstrdup(ce1->function) : NULL;
+			xdebug_llist_insert_next(fse->prev->profile.call_list, NULL, ce2);
+			//fprintf(stderr, "  moving '%s' from '%s' to '%s'\n", ce2->function,
+			//		tmp_name, prevname);
+		}
+		
+		xdebug_llist_empty(fse->profile.call_list, NULL);
+		xdfree(prevname);
+	} else {
+		/* update aggregate data with gross data */
+		if (XG(profiler_aggregate)) {
+			fse->aggr_entry->time_inclusive += fse->profile.time;
+			fse->aggr_entry->call_count++;
+		}
+	}
+	
+#if HAVE_PHP_MEMORY_USAGE
+	fprintf(XG(profile_file), "%d %lu %ld\n", default_lineno, (unsigned long) (net_time_taken * 10000000), (XG_MEMORY_USAGE() - fse->profile.memory) < 0 ? 0 : (XG_MEMORY_USAGE() - fse->profile.memory));
 #else
 	fprintf(XG(profile_file), "%d %lu\n", default_lineno, (unsigned long) (fse->profile.time * 10000000));
 #endif
-
+	
 	/* update aggregate data */
 	if (XG(profiler_aggregate)) {
-		fse->aggr_entry->time_own += fse->profile.time;
+		fse->aggr_entry->time_own += net_time_taken;
 #if HAVE_PHP_MEMORY_USAGE
-		fse->aggr_entry->mem_used += fse->memory;
+		fse->aggr_entry->mem_used += net_mem_used;
 #endif
 	}
-
+	
 	/* dump call list */
 	for (le = XDEBUG_LLIST_HEAD(fse->profile.call_list); le != NULL; le = XDEBUG_LLIST_NEXT(le))
 	{
 		xdebug_call_entry *call_entry = XDEBUG_LLIST_VALP(le);
-
+		
 		if (call_entry->user_defined == XDEBUG_EXTERNAL) {
 			fprintf(XG(profile_file), "cfn=%s\n", call_entry->function);
 		} else {
 			fprintf(XG(profile_file), "cfn=php::%s\n", call_entry->function);
 		}
 		
+		//fprintf(stderr, "  call item: %s\n", call_entry->function);
+
+		
 		fprintf(XG(profile_file), "calls=1 0 0\n");
 #if HAVE_PHP_MEMORY_USAGE
 		fprintf(XG(profile_file), "%d %lu %ld\n", call_entry->lineno, (unsigned long) (call_entry->time_taken * 10000000), call_entry->mem_used < 0 ? 0 : call_entry->mem_used);
@@ -253,8 +328,13 @@
 		fprintf(XG(profile_file), "%d %lu\n", call_entry->lineno, (unsigned long) (call_entry->time_taken * 10000000));
 #endif
 	}
+	
 	fprintf(XG(profile_file), "\n");
 	fflush(XG(profile_file));
+	xdfree(tmp_name);
+	
+	fse->profile.time = net_time_taken;
+	fse->memory = net_mem_used;
 }
 
 


