diff -r -U 3 --minimal ./original/nagios-3.0a3/base/checks.c ./develop/nagios-3.0a3/base/checks.c
--- ./original/nagios-3.0a3/base/checks.c	2007-04-10 15:46:00.000000000 +0100
+++ ./develop/nagios-3.0a3/base/checks.c	2007-05-21 13:11:55.678809000 +0100
@@ -1847,6 +1847,7 @@
 	/* reset latency, since on-demand checks have none */
 	hst->latency=0.0;
 
+        unmark_all_hosts(CHECKED_HOSTS_SET);
 	/* check route to the host (propagate problems and recoveries both up and down the tree) */
 	result=check_host(hst,PROPAGATE_TO_PARENT_HOSTS | PROPAGATE_TO_CHILD_HOSTS,check_options);
 
@@ -2000,6 +2001,10 @@
 	printf("check_host() start\n");
 #endif
 
+        if (host_is_marked(hst, CHECKED_HOSTS_SET)) {
+		return hst->current_state;
+        }
+        mark_host(hst, CHECKED_HOSTS_SET);
 	/* ADDED 06/20/2006 EG */
 	/* bail out if signal encountered */
 	if(sigrestart==TRUE || sigshutdown==TRUE)
@@ -2182,9 +2187,9 @@
 					/* check the parent host, assume its up if we can't find it, use the parent host's "old" status if we shouldn't propagate */
 					if(parent_host==NULL)
 						parent_result=HOST_UP;
-					else if(propagation_options & PROPAGATE_TO_PARENT_HOSTS)
-						parent_result=check_host(parent_host,PROPAGATE_TO_PARENT_HOSTS,check_options);
-					else
+					else if(propagation_options & PROPAGATE_TO_PARENT_HOSTS) {
+                                                parent_result=check_host(parent_host,PROPAGATE_TO_PARENT_HOSTS,check_options);
+					} else
 						parent_result=parent_host->current_state;
 
 					/* if this parent host was up, the route is okay */
diff -r -U 3 --minimal ./original/nagios-3.0a3/base/config.c ./develop/nagios-3.0a3/base/config.c
--- ./original/nagios-3.0a3/base/config.c	2007-03-25 17:25:12.000000000 +0100
+++ ./develop/nagios-3.0a3/base/config.c	2007-05-21 13:11:55.716770000 +0100
@@ -3178,38 +3178,6 @@
 
 
 	/********************************************/
-	/* check for circular paths between hosts   */
-	/********************************************/
-	if(verify_config==TRUE)
-		printf("Checking for circular paths between hosts...\n");
-
-	/* check routes between all hosts */
-	found=FALSE;
-	result=OK;
-	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-
-		/* clear checked flag for all hosts */
-		for(temp_host2=host_list;temp_host2!=NULL;temp_host2=temp_host2->next)
-			temp_host2->circular_path_checked=FALSE;
-
-		found=check_for_circular_host_path(temp_host,temp_host);
-		if(found==TRUE){
-			asprintf(&temp_buffer,"Error: There is a circular parent/child path that exists for host '%s'!",temp_host->name);
-			write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE);
-			my_free((void **)&temp_buffer);
-			result=ERROR;
-		        }
-	        }
-	if(result==ERROR)
-		errors++;
-
-#ifdef DEBUG1
-	printf("\tCompleted circular path checks\n");
-#endif
-
-
-
-	/********************************************/
 	/* check for circular dependencies         */
 	/********************************************/
 	if(verify_config==TRUE)
diff -r -U 3 --minimal ./original/nagios-3.0a3/cgi/outages.c ./develop/nagios-3.0a3/cgi/outages.c
--- ./original/nagios-3.0a3/cgi/outages.c	2006-03-21 21:38:10.000000000 +0000
+++ ./develop/nagios-3.0a3/cgi/outages.c	2007-05-21 13:11:56.834651000 +0100
@@ -571,13 +571,16 @@
 
 
 /* calculates network outage effect of a particular host being down or unreachable */
-void calculate_outage_effect_of_host(host *hst, int *affected_hosts, int *affected_services){
+static void calculate_outage_effect_of_host_rec(host *hst, int *affected_hosts, int *affected_services){
 	int total_child_hosts_affected=0;
 	int total_child_services_affected=0;
 	int temp_child_hosts_affected=0;
 	int temp_child_services_affected=0;
 	host *temp_host;
 
+        if (host_is_marked(hst, CALC_OUTAGE_SET))
+                return;
+        mark_host(hst, CALC_OUTAGE_SET);
 
 	/* find all child hosts of this host */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
@@ -587,7 +590,7 @@
 			continue;
 
 		/* calculate the outage effect of the child */
-		calculate_outage_effect_of_host(temp_host,&temp_child_hosts_affected,&temp_child_services_affected);
+		calculate_outage_effect_of_host_rec(temp_host,&temp_child_hosts_affected,&temp_child_services_affected);
 
 		/* keep a running total of outage effects */
 		total_child_hosts_affected+=temp_child_hosts_affected;
@@ -601,6 +604,11 @@
         }
 
 
+void calculate_outage_effect_of_host(host *hst, int *affected_hosts, int *affected_services){
+        unmark_all_hosts(CALC_OUTAGE_SET);
+        calculate_outage_effect_of_host_rec(hst, affected_hosts, affected_services);
+        unmark_all_hosts(CALC_OUTAGE_SET);
+}
 
 /* tests whether or not a host is "blocked" by upstream parents (host is already assumed to be down or unreachable) */
 int is_route_to_host_blocked(host *hst){
diff -r -U 3 --minimal ./original/nagios-3.0a3/cgi/statusmap.c ./develop/nagios-3.0a3/cgi/statusmap.c
--- ./original/nagios-3.0a3/cgi/statusmap.c	2006-03-21 21:38:10.000000000 +0000
+++ ./develop/nagios-3.0a3/cgi/statusmap.c	2007-05-21 13:11:56.879606000 +0100
@@ -138,6 +138,9 @@
 int host_child_depth_separation(host *, host *);
 int max_child_host_drawing_width(host *);
 int number_of_host_services(host *);
+int number_of_immediate_child_hosts(host *hst);
+int number_of_immediate_child_hosts_not_parents(host *hst);
+int number_of_immediate_parent_hosts(host *);				/* counts the number of immediate parents hosts for a particular host */
 
 void calculate_balanced_tree_coords(host *,int,int);
 void calculate_circular_coords(void);
@@ -278,6 +281,7 @@
 		return ERROR;
                 }
 
+        assign_host_depths();
 
 	document_header(TRUE);
 
@@ -898,7 +902,7 @@
 			this_host=find_host(host_name);
 
 		/* find total number of immediate parents/children for this host */
-		child_hosts=number_of_immediate_child_hosts(this_host);
+		child_hosts=number_of_immediate_child_hosts_not_parents(this_host);
 		parent_hosts=number_of_immediate_parent_hosts(this_host);
 
 		if(child_hosts==0 && parent_hosts==0)
@@ -1985,6 +1989,13 @@
 	printf("%d",number_of_immediate_child_hosts(hst));
 	printf("</b></td></tr>");
 
+	printf("<tr><td class=\\\"popupText\\\">Depth:</td><td class=\\\"popupText\\\"><b>");
+	printf("%d",hst->depth);
+	printf("</b></td></tr>");
+	printf("<tr><td class=\\\"popupText\\\">Min depth found:</td><td class=\\\"popupText\\\"><b>");
+	printf("%d",host_is_marked(hst,MIN_DEPTH_FOUND_SET));
+	printf("</b></td></tr>");
+
 	printf("</table>");
 
 	printf("<br><b><u>Services:</u></b><br>");
@@ -2394,40 +2405,17 @@
 
 /* calculates how many "layers" separate parent and child - used by collapsed tree layout method */
 int host_child_depth_separation(host *parent, host *child){
-	int this_depth=0;
-	int min_depth=0;
-	int have_min_depth=FALSE;
-	host *temp_host;
-
 	if(child==NULL)
 		return -1;
 
 	if(parent==child)
 		return 0;
 
-	if(is_host_immediate_child_of_host(parent,child)==TRUE)
-		return 1;
-
-	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
-
-			this_depth=host_child_depth_separation(temp_host,child);
-
-			if(this_depth>=0 && (have_min_depth==FALSE || (have_min_depth==TRUE && (this_depth<min_depth)))){
-				have_min_depth=TRUE;
-				min_depth=this_depth;
-			        }
-		        }
-	        }
-
-	if(have_min_depth==FALSE)
-		return -1;
-	else
-		return min_depth+1;
-        }
-
+        if (parent==NULL)
+                return child->depth;
 
+        return child->depth - parent->depth;
+}
 
 /* calculates how many hosts reside on a specific "layer" - used by collapsed tree layout method */
 int number_of_host_layer_members(host *parent, int layer){
@@ -2471,16 +2459,18 @@
 
 
 /* calculate max drawing width for host and children - used by balanced tree layout method */
-int max_child_host_drawing_width(host *parent){
+static int max_child_host_drawing_width_rec(host *parent){
 	host *temp_host;
 	int child_width=0;
 
 
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-		
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE)
-			child_width+=max_child_host_drawing_width(temp_host);
-	        }
+                if(is_host_immediate_child_of_host(parent,temp_host)==TRUE && host_is_marked(temp_host, MIN_DEPTH_FOUND_SET) && host_child_depth_separation(parent, temp_host) == 1)
+                        if (!host_is_marked(temp_host, DRAWING_WIDTH_SET)) {
+                                mark_host(temp_host, DRAWING_WIDTH_SET);
+                                child_width+=max_child_host_drawing_width_rec(temp_host);
+                        }
+        }
 
 	/* no children, so set width to 1 for this host */
 	if(child_width==0)
@@ -2490,7 +2480,14 @@
 		return child_width;
         }
 
+int max_child_host_drawing_width(host *parent){
+        int child_width;
 
+        unmark_all_hosts(DRAWING_WIDTH_SET);
+        child_width = max_child_host_drawing_width_rec(parent);
+        unmark_all_hosts(DRAWING_WIDTH_SET);
+        return child_width;
+}
 
 /* calculates number of services associated with a particular service */
 int number_of_host_services(host *hst){
@@ -2511,18 +2508,66 @@
 	
 
 
+/* returns a count of the immediate children for a given host */
+int number_of_immediate_child_hosts(host *hst){
+	int children=0;
+	host *temp_host=NULL;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+		if(is_host_immediate_child_of_host(hst,temp_host)==TRUE && host_is_marked(temp_host, MIN_DEPTH_FOUND_SET) && host_child_depth_separation(hst, temp_host) == 1)
+			children++;
+		}
+
+	return children;
+	}
+
+
+/* returns a count of the immediate children for a given host */
+int number_of_immediate_child_hosts_not_parents(host *hst){
+	int children=0;
+	host *temp_host;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+		if(is_host_immediate_child_of_host(hst,temp_host)==TRUE && host_is_marked(temp_host, MIN_DEPTH_FOUND_SET) && host_child_depth_separation(hst, temp_host) == 1 && is_host_immediate_parent_of_host(hst,temp_host)==FALSE)
+			children++;
+		}
+
+	return children;
+	}
+
+
+/* get the number of immediate parent hosts for a given host */
+int number_of_immediate_parent_hosts(host *hst){
+	int parents=0;
+	host *temp_host=NULL;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+		if(is_host_immediate_parent_of_host(hst,temp_host)==TRUE && host_is_marked(temp_host, MIN_DEPTH_FOUND_SET) && host_child_depth_separation(temp_host, hst) == 1){
+			parents++;
+			break;
+		        }
+	        }
+
+	return parents;
+        }
+
+
 /******************************************************************/
 /***************** COORDINATE CALCULATION FUNCTIONS ***************/
 /******************************************************************/
 
 /* calculates coords of a host's children - used by balanced tree layout method */
-void calculate_balanced_tree_coords(host *parent, int x, int y){
+static void calculate_balanced_tree_coords_rec(host *parent, int x, int y){
 	int parent_drawing_width;
 	int start_drawing_x;
 	int current_drawing_x;
 	int this_drawing_width;
 	host *temp_host;
 
+        if (host_is_marked(parent, CALC_BALANCED_SET))
+                return;
+        mark_host(parent, CALC_BALANCED_SET);
+
 	/* calculate total drawing width of parent host */
 	parent_drawing_width=max_child_host_drawing_width(parent);
 
@@ -2534,7 +2579,7 @@
 	/* calculate coords for children */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE && host_child_depth_separation(parent, temp_host) == 1){
 
 			/* get drawing width of child host */
 			this_drawing_width=max_child_host_drawing_width(temp_host);
@@ -2547,7 +2592,7 @@
 			current_drawing_x+=(this_drawing_width*DEFAULT_NODE_WIDTH)+((this_drawing_width-1)*DEFAULT_NODE_HSPACING)+DEFAULT_NODE_HSPACING;
 
 			/* recurse into child host ... */
-			calculate_balanced_tree_coords(temp_host,temp_host->x_2d,temp_host->y_2d);
+			calculate_balanced_tree_coords_rec(temp_host,temp_host->x_2d,temp_host->y_2d);
 		        }
 
 	        }
@@ -2555,6 +2600,11 @@
 	return;
         }
 
+void calculate_balanced_tree_coords(host *parent, int x, int y){
+        unmark_all_hosts(CALC_BALANCED_SET);
+        calculate_balanced_tree_coords_rec(parent, x, y);
+        unmark_all_hosts(CALC_BALANCED_SET);
+}
 
 /* calculate coords of all hosts in circular layout method */
 void calculate_circular_coords(void){
@@ -2606,7 +2656,7 @@
 	
 
 /* calculates coords of all hosts in a particular "layer" in circular layout method */
-void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+static void calculate_circular_layer_coords_rec(host *parent, double start_angle, double useable_angle, int layer, int radius){
 	int parent_drawing_width=0;
 	int this_drawing_width=0;
 	int immediate_children=0;
@@ -2619,6 +2669,9 @@
 	double y_coord=0.0;
 	host *temp_host;
 
+        if (host_is_marked(parent, LAYER_COORDS_SET))
+                return;
+        mark_host(parent, LAYER_COORDS_SET);
 
 	/* get the total number of immediate children to this host */
 	immediate_children=number_of_immediate_child_hosts(parent);
@@ -2640,7 +2693,7 @@
 	/* calculate coords for children */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE && host_child_depth_separation(parent, temp_host) == 1){
 
 			/* get drawing width of child host */
 			this_drawing_width=max_child_host_drawing_width(temp_host);
@@ -2673,7 +2726,7 @@
 			temp_host->should_be_drawn=TRUE;
 
 			/* recurse into child host ... */
-			calculate_circular_layer_coords(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
+			calculate_circular_layer_coords_rec(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
 
 			/* increment current drawing angle */
 			current_drawing_angle+=available_angle;
@@ -2684,10 +2737,16 @@
         }
 
 
+void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+        unmark_all_hosts(LAYER_COORDS_SET);
+        calculate_circular_layer_coords_rec(parent, start_angle, useable_angle, layer, radius);
+        unmark_all_hosts(LAYER_COORDS_SET);
+}
 
 /* draws background "extras" for all hosts in circular markup layout */
 void draw_circular_markup(void){
 
+        unmark_all_hosts(DRAW_CIRCULAR_SET);
 	/* calculate all host sections, starting with first layer */
 	draw_circular_layer_markup(NULL,0.0,360.0,1,CIRCULAR_DRAWING_RADIUS);
 
@@ -2718,6 +2777,10 @@
 	int translated_x=0;
 	int translated_y=0;
 
+        if (host_is_marked(parent, DRAW_CIRCULAR_SET))
+                return;
+        mark_host(parent, DRAW_CIRCULAR_SET);
+
 	/* get the total number of immediate children to this host */
 	immediate_children=number_of_immediate_child_hosts(parent);
 
@@ -2737,7 +2800,7 @@
 	/* calculate coords for children */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE && host_child_depth_separation(parent, temp_host) == 1){
 
 			/* get drawing width of child host */
 			this_drawing_width=max_child_host_drawing_width(temp_host);
diff -r -U 3 --minimal ./original/nagios-3.0a3/cgi/statuswrl.c ./develop/nagios-3.0a3/cgi/statuswrl.c
--- ./original/nagios-3.0a3/cgi/statuswrl.c	2006-03-27 21:53:55.000000000 +0100
+++ ./develop/nagios-3.0a3/cgi/statuswrl.c	2007-05-21 13:11:56.904582000 +0100
@@ -82,6 +82,9 @@
 int max_child_host_layer_members(host *);
 int host_child_depth_separation(host *, host *);
 int max_child_host_drawing_width(host *);
+int number_of_immediate_child_hosts(host *hst);
+int number_of_immediate_child_hosts_not_parents(host *hst);
+int number_of_immediate_parent_hosts(host *);				/* counts the number of immediate parents hosts for a particular host */
 
 void calculate_balanced_tree_coords(host *,int,int);
 void calculate_circular_coords(void);
@@ -466,17 +469,18 @@
 	return max_members;
         }
 
-
-
 /* calculate max drawing width for host and children - used by balanced tree layout method */
-int max_child_host_drawing_width(host *parent){
+int max_child_host_drawing_width_rec(host *parent){
 	host *temp_host;
 	int child_width=0;
 
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE)
-			child_width+=max_child_host_drawing_width(temp_host);
-	        }
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE && host_is_marked(temp_host, MIN_DEPTH_FOUND_SET) && host_child_depth_separation(parent, temp_host) == 1)
+                        if (!host_is_marked(temp_host, DRAWING_WIDTH_SET)) {
+                                mark_host(temp_host, DRAWING_WIDTH_SET);
+                                child_width+=max_child_host_drawing_width_rec(temp_host);
+                        }
+                }
 
 	/* no children, so set width to 1 for this host */
 	if(child_width==0)
@@ -485,6 +489,15 @@
 	else
 		return child_width;
         }
+
+int max_child_host_drawing_width(host *parent){
+        int child_width;
+
+        unmark_all_hosts(DRAWING_WIDTH_SET);
+        child_width = max_child_host_drawing_width_rec(parent);
+        unmark_all_hosts(DRAWING_WIDTH_SET);
+        return child_width;
+}
 	
 
 
@@ -1166,18 +1179,66 @@
 
 
 
+/* returns a count of the immediate children for a given host */
+int number_of_immediate_child_hosts(host *hst){
+	int children=0;
+	host *temp_host=NULL;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+		if(is_host_immediate_child_of_host(hst,temp_host)==TRUE && host_is_marked(temp_host, MIN_DEPTH_FOUND_SET) && host_child_depth_separation(hst, temp_host) == 1)
+			children++;
+		}
+
+	return children;
+	}
+
+
+/* returns a count of the immediate children for a given host */
+int number_of_immediate_child_hosts_not_parents(host *hst){
+	int children=0;
+	host *temp_host;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+		if(is_host_immediate_child_of_host(hst,temp_host)==TRUE && host_is_marked(temp_host, MIN_DEPTH_FOUND_SET) && host_child_depth_separation(hst, temp_host) == 1 && is_host_immediate_parent_of_host(hst,temp_host)==FALSE)
+			children++;
+		}
+
+	return children;
+	}
+
+
+/* get the number of immediate parent hosts for a given host */
+int number_of_immediate_parent_hosts(host *hst){
+	int parents=0;
+	host *temp_host=NULL;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+		if(is_host_immediate_parent_of_host(hst,temp_host)==TRUE && host_is_marked(temp_host, MIN_DEPTH_FOUND_SET) && host_child_depth_separation(temp_host, hst) == 1){
+			parents++;
+			break;
+		        }
+	        }
+
+	return parents;
+        }
+
+
 /******************************************************************/
 /***************** COORDINATE CALCULATION FUNCTIONS ***************/
 /******************************************************************/
 
 /* calculates coords of a host's children - used by balanced tree layout method */
-void calculate_balanced_tree_coords(host *parent, int x, int y){
+static void calculate_balanced_tree_coords_rec(host *parent, int x, int y){
 	int parent_drawing_width;
 	int start_drawing_x;
 	int current_drawing_x;
 	int this_drawing_width;
 	host *temp_host;
 
+        if (host_is_marked(parent, CALC_BALANCED_SET))
+                return;
+        mark_host(parent, CALC_BALANCED_SET);
+
 	/* calculate total drawing width of parent host */
 	parent_drawing_width=max_child_host_drawing_width(parent);
 
@@ -1189,7 +1250,7 @@
 	/* calculate coords for children */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE && host_child_depth_separation(parent, temp_host) == 1){
 
 			/* get drawing width of child host */
 			this_drawing_width=max_child_host_drawing_width(temp_host);
@@ -1202,7 +1263,7 @@
 			current_drawing_x+=(this_drawing_width*DEFAULT_NODE_WIDTH)+((this_drawing_width-1)*DEFAULT_NODE_HSPACING)+DEFAULT_NODE_HSPACING;
 
 			/* recurse into child host ... */
-			calculate_balanced_tree_coords(temp_host,temp_host->x_3d,temp_host->y_3d);
+			calculate_balanced_tree_coords_rec(temp_host,temp_host->x_3d,temp_host->y_3d);
 		        }
 
 	        }
@@ -1210,6 +1271,11 @@
 	return;
         }
 
+void calculate_balanced_tree_coords(host *parent, int x, int y){
+        unmark_all_hosts(CALC_BALANCED_SET);
+        calculate_balanced_tree_coords_rec(parent, x, y);
+        unmark_all_hosts(CALC_BALANCED_SET);
+}
 
 /* calculate coords of all hosts in circular layout method */
 void calculate_circular_coords(void){
@@ -1222,7 +1288,7 @@
 	
 
 /* calculates coords of all hosts in a particular "layer" in circular layout method */
-void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+static void calculate_circular_layer_coords_rec(host *parent, double start_angle, double useable_angle, int layer, int radius){
 	int parent_drawing_width=0;
 	int this_drawing_width=0;
 	int immediate_children=0;
@@ -1235,6 +1301,9 @@
 	double y_coord=0.0;
 	host *temp_host;
 
+        if (host_is_marked(parent, LAYER_COORDS_SET))
+                return;
+        mark_host(parent, LAYER_COORDS_SET);
 
 	/* get the total number of immediate children to this host */
 	immediate_children=number_of_immediate_child_hosts(parent);
@@ -1256,7 +1325,7 @@
 	/* calculate coords for children */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE && host_child_depth_separation(parent, temp_host) == 1){
 
 			/* get drawing width of child host */
 			this_drawing_width=max_child_host_drawing_width(temp_host);
@@ -1289,7 +1358,7 @@
 			temp_host->should_be_drawn=TRUE;
 
 			/* recurse into child host ... */
-			calculate_circular_layer_coords(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
+			calculate_circular_layer_coords_rec(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
 
 			/* increment current drawing angle */
 			current_drawing_angle+=available_angle;
@@ -1299,4 +1368,8 @@
 	return;
         }
 
-
+void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+        unmark_all_hosts(LAYER_COORDS_SET);
+        calculate_circular_layer_coords_rec(parent, start_angle, useable_angle, layer, radius);
+        unmark_all_hosts(LAYER_COORDS_SET);
+}
diff -r -U 3 --minimal ./original/nagios-3.0a3/cgi/tac.c ./develop/nagios-3.0a3/cgi/tac.c
--- ./original/nagios-3.0a3/cgi/tac.c	2006-08-22 17:19:07.000000000 +0100
+++ ./develop/nagios-3.0a3/cgi/tac.c	2007-05-21 13:11:56.926559000 +0100
@@ -820,11 +820,14 @@
 
 
 /* calculates network outage effect of a particular host being down or unreachable */
-void calculate_outage_effect_of_host(host *hst, int *affected_hosts){
+static void calculate_outage_effect_of_host_rec(host *hst, int *affected_hosts){
 	int total_child_hosts_affected=0;
 	int temp_child_hosts_affected=0;
 	host *temp_host;
 
+        if (host_is_marked(hst, CALC_OUTAGE_SET))
+                return;
+        mark_host(hst, CALC_OUTAGE_SET);
 
 	/* find all child hosts of this host */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
@@ -834,7 +837,7 @@
 			continue;
 
 		/* calculate the outage effect of the child */
-		calculate_outage_effect_of_host(temp_host,&temp_child_hosts_affected);
+		calculate_outage_effect_of_host_rec(temp_host,&temp_child_hosts_affected);
 
 		/* keep a running total of outage effects */
 		total_child_hosts_affected+=temp_child_hosts_affected;
@@ -845,6 +848,11 @@
 	return;
         }
 
+void calculate_outage_effect_of_host(host *hst, int *affected_hosts){
+        unmark_all_hosts(CALC_OUTAGE_SET);
+        calculate_outage_effect_of_host_rec(hst, affected_hosts);
+        unmark_all_hosts(CALC_OUTAGE_SET);
+}
 
 
 /* tests whether or not a host is "blocked" by upstream parents (host is already assumed to be down or unreachable) */
diff -r -U 3 --minimal ./original/nagios-3.0a3/common/objects.c ./develop/nagios-3.0a3/common/objects.c
--- ./original/nagios-3.0a3/common/objects.c	2007-04-02 17:02:54.000000000 +0100
+++ ./develop/nagios-3.0a3/common/objects.c	2007-05-21 13:11:58.740743000 +0100
@@ -3614,6 +3614,79 @@
 
 
 
+/************************************/
+/***** Graph traversal routines *****/
+/************************************/
+
+void unmark_all_hosts(int set){
+        host *temp_host;
+
+       	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+                temp_host->visited &= ~set;
+        }
+}
+
+void unmark_host(host *hst, int set){
+        hst->visited &= ~set;
+}
+void mark_host(host *hst, int set){
+        if (hst != NULL)
+                hst->visited |= set;
+}
+
+int host_is_marked(host *hst, int set){
+        return hst != NULL && (hst->visited & set);
+}
+
+static int assign_host_depth_rec(host *hst){
+        hostsmember *temp_hostsmember;
+        int min_depth_found = FALSE;
+	int i;
+
+	if (host_is_marked(hst, MIN_DEPTH_FOUND_SET)) {
+		return TRUE;
+	}
+        if (host_is_marked(hst, DEPTH_VISITING_SET)) {
+                return host_is_marked(hst, MIN_DEPTH_FOUND_SET);
+	}
+
+        mark_host(hst, DEPTH_VISITING_SET);
+        if (hst->parent_hosts == NULL) {
+                mark_host(hst, MIN_DEPTH_FOUND_SET);
+                min_depth_found = TRUE;
+                hst->depth = 1;
+        } else {
+                hst->depth = -1;
+                for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next) {
+                        host *temp_host = find_host(temp_hostsmember->host_name);
+                        if (assign_host_depth_rec(temp_host)) {
+				min_depth_found = TRUE;
+				if (hst->depth == -1 || temp_host->depth + 1 < hst->depth) {
+					hst->depth = temp_host->depth + 1;
+				}
+			}
+                }
+                if (min_depth_found)
+                        mark_host(hst, MIN_DEPTH_FOUND_SET);
+                else
+                        hst->depth = 1;
+
+        }
+        unmark_host(hst, DEPTH_VISITING_SET);
+        return min_depth_found;
+}
+
+void assign_host_depths(void){
+        host *temp_host;
+        int min_depth = 0;
+
+        unmark_all_hosts(DEPTH_VISITING_SET|MIN_DEPTH_FOUND_SET);
+
+       	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+                assign_host_depth_rec(temp_host);
+        }
+}
+
 /******************************************************************/
 /********************* OBJECT QUERY FUNCTIONS *********************/
 /******************************************************************/
@@ -3688,20 +3761,6 @@
 	}
 
 
-/* returns a count of the immediate children for a given host */
-int number_of_immediate_child_hosts(host *hst){
-	int children=0;
-	host *temp_host=NULL;
-
-	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-		if(is_host_immediate_child_of_host(hst,temp_host)==TRUE)
-			children++;
-		}
-
-	return children;
-	}
-
-
 /* returns a count of the total children for a given host */
 int number_of_total_child_hosts(host *hst){
 	int children=0;
@@ -3716,22 +3775,6 @@
 	}
 
 
-/* get the number of immediate parent hosts for a given host */
-int number_of_immediate_parent_hosts(host *hst){
-	int parents=0;
-	host *temp_host=NULL;
-
-	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-		if(is_host_immediate_parent_of_host(hst,temp_host)==TRUE){
-			parents++;
-			break;
-		        }
-	        }
-
-	return parents;
-        }
-
-
 /* get the total number of parent hosts for a given host */
 int number_of_total_parent_hosts(host *hst){
 	int parents=0;
diff -r -U 3 --minimal ./original/nagios-3.0a3/include/objects.h ./develop/nagios-3.0a3/include/objects.h
--- ./original/nagios-3.0a3/include/objects.h	2007-04-02 17:02:55.000000000 +0100
+++ ./develop/nagios-3.0a3/include/objects.h	2007-05-21 13:12:00.387096000 +0100
@@ -65,7 +65,17 @@
 #define HOSTESCALATION_HASHSLOTS               1024
 #define SERVICEESCALATION_HASHSLOTS            1024
 
+/****************** SET IDENTIFIERS *******************/
 
+#define CHECKED_HOSTS_SET   (1<<0)
+#define DEPTH_VISITING_SET  (1<<1)
+#define MIN_DEPTH_FOUND_SET (1<<2)
+#define LAYER_MEMBERS_SET   (1<<3)
+#define LAYER_COORDS_SET    (1<<4)
+#define DRAWING_WIDTH_SET   (1<<5)
+#define DRAW_CIRCULAR_SET   (1<<6)
+#define CALC_BALANCED_SET   (1<<7)
+#define CALC_OUTAGE_SET     (1<<8)
 
 /****************** DATA STRUCTURES *******************/
 
@@ -357,6 +367,8 @@
 	timeperiod *notification_period_ptr;
 	objectlist *hostgroups_ptr;
 #endif
+        int     visited;
+        int     depth;
 	struct  host_struct *next;
 	struct  host_struct *nexthash;
         };
@@ -635,6 +647,8 @@
 /**** Top-level input functions ****/
 int read_object_config_data(char *,int,int,int);        /* reads all external configuration data of specific types */
 
+void assign_host_depths(void);
+
 /**** Object Creation Functions ****/
 contact *add_contact(char *,char *,char *,char *,char **,char *,char *,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int);	/* adds a contact definition */
 commandsmember *add_service_notification_command_to_contact(contact *,char *);				/* adds a service notification command to a contact definition */
@@ -742,9 +756,7 @@
 int is_escalated_contact_for_service(service *,contact *);              /* checks whether or not a contact is an escalated contact for a specific service */
 int is_host_immediate_parent_of_host(host *,host *);		        /* tests whether or not a host is an immediate parent of another host */
 
-int number_of_immediate_child_hosts(host *);		                /* counts the number of immediate child hosts for a particular host */
 int number_of_total_child_hosts(host *);				/* counts the number of total child hosts for a particular host */
-int number_of_immediate_parent_hosts(host *);				/* counts the number of immediate parents hosts for a particular host */
 int number_of_total_parent_hosts(host *);				/* counts the number of total parents hosts for a particular host */
 
 #ifdef NSCORE
@@ -757,6 +769,12 @@
 /**** Object Cleanup Functions ****/
 int free_object_data(void);                             /* frees all allocated memory for the object definitions */
 
+/**** set membership functions ****/
+extern void unmark_all_hosts(int set);
+extern void mark_host(host *hst, int set);
+extern void unmark_host(host *hst, int set);
+extern int host_is_marked(host *hst, int set);
+
 #ifdef __cplusplus
   }
 #endif
