diff --git a/main/pbx.c b/main/pbx.c
index d72607579c97aca8ba0090953f9b636e84f70293..48f56fba0ae90e1f0d96aaf5e4b1cdc2058529e7 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -316,9 +316,10 @@ static int pbx_builtin_saydigits(struct ast_channel *, void *);
 static int pbx_builtin_saycharacters(struct ast_channel *, void *);
 static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
 int pbx_builtin_setvar(struct ast_channel *, void *);
+void log_match_char_tree(struct match_char *node, char *prefix); /* for use anywhere */
 static int pbx_builtin_setvar_multiple(struct ast_channel *, void *);
 static int pbx_builtin_importvar(struct ast_channel *, void *);
-static void set_ext_pri(struct ast_channel *c, const char *exten, int pri);
+static void set_ext_pri(struct ast_channel *c, const char *exten, int pri); 
 static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid);
 static struct match_char *already_in_tree(struct match_char *current, char *pat);
 static struct match_char *add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly);
@@ -851,6 +852,48 @@ static void update_scoreboard(struct scoreboard *board, int length, int spec, st
 	}
 }
 
+void log_match_char_tree(struct match_char *node, char *prefix)
+{
+	char my_prefix[1024];
+	char extenstr[40];
+	
+	extenstr[0] = 0;
+	if (node && node->exten && node->exten)
+		sprintf(extenstr,"(%p)",node->exten);
+	
+	if (strlen(node->x) > 1 )
+		ast_log(LOG_DEBUG,"%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
+	else
+		ast_log(LOG_DEBUG,"%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
+	strcpy(my_prefix,prefix);
+	strcat(my_prefix,"+       ");
+	if (node->next_char)
+		log_match_char_tree(node->next_char, my_prefix);
+	if (node->alt_char)
+		log_match_char_tree(node->alt_char, prefix);
+}
+
+static void cli_match_char_tree(struct match_char *node, char *prefix, int fd)
+{
+	char my_prefix[1024];
+	char extenstr[40];
+	
+	extenstr[0] = 0;
+	if (node && node->exten && node->exten)
+		sprintf(extenstr,"(%p)",node->exten);
+	
+	if (strlen(node->x) > 1)
+		ast_cli(fd, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
+	else
+		ast_cli(fd, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
+	strcpy(my_prefix,prefix);
+	strcat(my_prefix,"+       ");
+	if (node->next_char)
+		cli_match_char_tree(node->next_char, my_prefix, fd);
+	if (node->alt_char)
+		cli_match_char_tree(node->alt_char, prefix, fd);
+}
+
 static struct ast_exten *get_canmatch_exten(struct match_char *node)
 {
 	/* find the exten at the end of the rope */
@@ -3618,76 +3661,82 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension
 {
 	struct ast_exten *exten, *prev_exten = NULL;
 	struct ast_exten *peer;
+	struct ast_exten ex, *exten2, *exten3;
+	char dummy_name[1024];
 
 	ast_wrlock_context(con);
 
 	/* Handle this is in the new world */
 
-	if (con->pattern_tree) {
-		struct ast_exten ex, *exten2, *exten3;
-		char dummy_name[1024];
-
 #ifdef NEED_DEBUG
-		ast_log(LOG_NOTICE,"Removing %s/%s/%d from trees, registrar=%s\n", con->name, extension, priority, registrar);
+	ast_log(LOG_NOTICE,"Removing %s/%s/%d from trees, registrar=%s\n", con->name, extension, priority, registrar);
 #endif
-		/* find this particular extension */
-		ex.exten = dummy_name;
-		ex.matchcid = 0;
-		ast_copy_string(dummy_name,extension, sizeof(dummy_name));
-		exten = ast_hashtab_lookup(con->root_tree, &ex);
-		if (exten) {
-			if (priority == 0)
-			{
-				/* success, this exten is in this pattern tree. */
+	/* find this particular extension */
+	ex.exten = dummy_name;
+	ex.matchcid = 0;
+	ast_copy_string(dummy_name,extension, sizeof(dummy_name));
+	exten = ast_hashtab_lookup(con->root_tree, &ex);
+	if (exten) {
+		if (priority == 0)
+		{
+			exten2 = ast_hashtab_remove_this_object(con->root_tree, exten);
+			if (!exten2)
+				ast_log(LOG_ERROR,"Trying to delete the exten %s from context %s, but could not remove from the root_tree\n", extension, con->name);
+			if (con->pattern_tree) {
+				
 				struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
+				
 				if (x->exten) { /* this test for safety purposes */
 					x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
 					x->exten = 0; /* get rid of what will become a bad pointer */
-					exten2 = ast_hashtab_remove_this_object(con->root_tree, exten);
 				} else {
 					ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
 				}
-			} else {
-				ex.priority = priority;
-				exten2 = ast_hashtab_lookup(exten->peer_tree, &ex);
-				if (exten2) {
-					
-					if (exten2->label) { /* if this exten has a label, remove that, too */
-						exten3 = ast_hashtab_remove_this_object(exten->peer_label_tree,exten2);
-						if (!exten3)
-							ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_tree of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten);
-					}
-							
-					exten3 = ast_hashtab_remove_this_object(exten->peer_tree, exten2);
+			}
+		} else {
+			ex.priority = priority;
+			exten2 = ast_hashtab_lookup(exten->peer_tree, &ex);
+			if (exten2) {
+				
+				if (exten2->label) { /* if this exten has a label, remove that, too */
+					exten3 = ast_hashtab_remove_this_object(exten->peer_label_tree,exten2);
+					if (!exten3)
+						ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_tree of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten);
+				}
+				
+				exten3 = ast_hashtab_remove_this_object(exten->peer_tree, exten2);
+				if (!exten3)
+					ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_tree of context %s, extension %s!\n", priority, con->name, exten2->exten);
+				if (ast_hashtab_size(exten->peer_tree) == 0) {
+					/* well, if the last priority of an exten is to be removed,
+					   then, the extension is removed, too! */
+					exten3 = ast_hashtab_remove_this_object(con->root_tree, exten);
 					if (!exten3)
-						ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_tree of context %s, extension %s!\n", priority, con->name, exten2->exten);
-					if (ast_hashtab_size(exten->peer_tree) == 0) {
-						/* well, if the last priority of an exten is to be removed,
-						   then, the extension is removed, too! */
+						ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_tree (%s) (priority %d)\n", exten->exten, con->name, priority);
+					if (con->pattern_tree) {
 						struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
 						if (x->exten) { /* this test for safety purposes */
 							x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
 							x->exten = 0; /* get rid of what will become a bad pointer */
-							exten3 = ast_hashtab_remove_this_object(con->root_tree, exten);
-							if (!exten3)
-								ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_tree (%s) (priority %d)\n", exten->exten, con->name, priority);
 						}
 					}
-				} else {
-					ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
-							priority, exten->exten, con->name);
 				}
+			} else {
+				ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
+						priority, exten->exten, con->name);
 			}
-		} else {
-			/* hmmm? this exten is not in this pattern tree? */
-			ast_log(LOG_WARNING,"Cannot find extension %s in pattern tree in context %s\n",
-					extension, con->name);
 		}
+	} else {
+		/* hmmm? this exten is not in this pattern tree? */
+		ast_log(LOG_WARNING,"Cannot find extension %s in root_tree in context %s\n",
+				extension, con->name);
+	}
 #ifdef NEED_DEBUG
+	if (con->pattern_tree) {
 		ast_log(LOG_NOTICE,"match char tree after exten removal:\n");
 		log_match_char_tree(con->pattern_tree, " ");
-#endif
 	}
+#endif
 	
 
 	/* scan the extension list to find matching extension-registrar */
@@ -4389,6 +4438,7 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten,
 			ast_cli(fd,    "                              [matched exten]: If all chars matched to this point, which extension this matches. In form: EXTEN:<exten string> \r\n");
 			ast_cli(fd,    "                        In general, you match a trie node to a string character, from left to right. All possible matching chars\r\n");
 			ast_cli(fd,    "                        are in a string vertically, separated by an unbroken string of '+' characters.\r\n\r\n");
+			cli_match_char_tree(c->pattern_tree, " ", fd);
 		}
 
 		ast_unlock_context(c);