diff --git a/Makefile b/Makefile
index d62c6a07939f51d0a09c41079b6ef09c83116bd0..d2e48c259591b8f4aed2f4241fa9fac2674aa417 100755
--- a/Makefile
+++ b/Makefile
@@ -232,6 +232,7 @@ samples: all datafiles adsi
 		fi ; \
 		install $$x $(ASTETCDIR)/`basename $$x .sample` ;\
 	done
+	echo "[directories]" > $(ASTETCDIR)/asterisk.conf
 	echo "astetcdir => $(ASTETCDIR)" >> $(ASTETCDIR)/asterisk.conf
 	echo "astmoddir => $(MODULES_DIR)" >> $(ASTETCDIR)/asterisk.conf
 	echo "astvarlibdir => $(ASTVARLIBDIR)" >> $(ASTETCDIR)/asterisk.conf
diff --git a/app.c b/app.c
index 2a8c12ef945ac3dc19c2928348c4b419f3c55cde..192b9d99ac05339f864e5fc718c20b92786fdb7d 100755
--- a/app.c
+++ b/app.c
@@ -146,10 +146,24 @@ int ast_app_has_voicemail(char *mailbox)
 	DIR *dir;
 	struct dirent *de;
 	char fn[256];
-
+	char tmp[256]="";
+	char *mb, *cur;
+	int ret;
 	/* If no mailbox, return immediately */
 	if (!strlen(mailbox))
 		return 0;
+	if (strchr(mailbox, ',')) {
+		strncpy(tmp, mailbox, sizeof(tmp));
+		mb = tmp;
+		ret = 0;
+		while((cur = strsep(&mb, ", "))) {
+			if (strlen(cur)) {
+				if (ast_app_has_voicemail(cur))
+					return 1; 
+			}
+		}
+		return 0;
+	}
 	snprintf(fn, sizeof(fn), "%s/vm/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, mailbox);
 	dir = opendir(fn);
 	if (!dir)
diff --git a/apps/Makefile b/apps/Makefile
index 7a7d93771d7e79386f229ad83e202606f71cda26..48e69c76a4a32626806fd80e03a03c5a55b968c1 100755
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -24,7 +24,7 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom.
 #APPS+=app_sql_postgres.so
 #APPS+=app_sql_odbc.so
 
-APPS+=$(shell if [ -f /usr/include/zap.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so" ; fi)
+APPS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so" ; fi)
 #APPS+=$(shell if [ -f /usr/include/zap.h ]; then echo "app_rpt.so" ; fi)
 
 CFLAGS+=
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 0646b0601f88aca3608b762c8aa554637889eccb..3ea6cff461fba90f5e0b5072a29ea9392be2ad2c 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -22,6 +22,7 @@
 #include <asterisk/module.h>
 #include <asterisk/adsi.h>
 #include <asterisk/app.h>
+#include <asterisk/manager.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
@@ -726,6 +727,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
 		ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
 	ast_destroy(cfg);
 	/* Leave voicemail for someone */
+	manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext, ast_app_has_voicemail(ext));
 	return res;
 }
 
@@ -1981,6 +1983,9 @@ out2:
 		ast_destroy(cfg);
 	if (useadsi)
 		adsi_unload_session(chan);
+	if (valid) {
+		manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", username, ast_app_has_voicemail(username));
+	}
 	LOCAL_USER_REMOVE(u);
 	return res;
 
diff --git a/channel.c b/channel.c
index 6e6638c588bb828a66dd5dfdae238f1c12d9385c..6a32fd3fd6603e890a79df322d19b6e484422ac5 100755
--- a/channel.c
+++ b/channel.c
@@ -1560,6 +1560,7 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe
 
 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
 {
+	struct ast_frame null = { AST_FRAME_NULL, };
 	ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
 		clone->name, original->name);
 	if (original->masq) {
@@ -1574,6 +1575,9 @@ int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clo
 	}
 	original->masq = clone;
 	clone->masqr = original;
+	/* XXX can't really hold the lock here, but at the same time, it' s
+	   not really safe not to XXX */
+	ast_queue_frame(original, &null, 0);
 	return 0;
 }
 
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index fa0c1fa817ec34ae946a0b4cdc82d5ed36abab07..b71459b6d851d2b1d43619323034a9c783a31f93 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1163,8 +1163,12 @@ static int sip_register(char *value, int lineno)
 		return -1;
 	strncpy(copy, value, sizeof(copy)-1);
 	stringp=copy;
-	username = strsep(&stringp, "@");
-	hostname = strsep(&stringp, "@");
+	username = stringp;
+	hostname = strrchr(stringp, '@');
+	if (hostname) {
+		*hostname = '\0';
+		hostname++;
+	}
 	if (!hostname) {
 		ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno);
 		return -1;
@@ -2325,10 +2329,10 @@ static int get_refer_info(struct sip_pvt *p, struct sip_request *oreq)
 		*a2 = '\0';
 	
 	
-	if (sipdebug)
+	if (sipdebug) {
 		ast_verbose("Looking for %s in %s\n", c, p->context);
 		ast_verbose("Looking for %s in %s\n", c2, p->context);
-		
+	}
 	if (strlen(tmp5)) {	
 		/* This is a supervised transfer */
 		ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",tmp5);
@@ -2355,7 +2359,7 @@ static int get_refer_info(struct sip_pvt *p, struct sip_request *oreq)
 			return 0;
 		else
 			ast_log(LOG_NOTICE, "Supervised transfer requested, but unable to find callid '%s'\n", tmp5);
-	} else if (ast_exists_extension(NULL, p->context, c, 1, NULL) && ast_exists_extension(NULL, p->context, c2, 1, NULL)) {
+	} else if (ast_exists_extension(NULL, p->context, c, 1, NULL)) {
 		/* This is an unsupervised transfer */
 		ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c);
 		ast_log(LOG_DEBUG,"Assigning Extension %s to REFERRED-BY\n", c2);
@@ -3294,6 +3298,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
 						ast_async_goto(transfer_to,"", p->refer_to,1, 1);
 				}
 			}
+			transmit_request(p, "BYE", p->outgoing);
 		}
 	} else if (!strcasecmp(cmd, "CANCEL") || !strcasecmp(cmd, "BYE")) {
 		copy_request(&p->initreq, req);
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index 59e036d7c0f42843e5b43f475d7e50c5023723b8..23cc2fb5b5b2143d54f1892230fdebbffbe69d0c 100755
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -1,11 +1,11 @@
 /*
  * Asterisk -- A telephony toolkit for Linux.
  *
- * Tormenta T1 Card (via Zapata library) support 
+ * Zaptel Pseudo TDM interface 
  * 
- * Copyright (C) 1999, Mark Spencer
+ * Copyright (C) 2003 Digium
  *
- * Mark Spencer <markster@linux-support.net>
+ * Mark Spencer <markster@digium.com>
  *
  * This program is free software, distributed under the terms of
  * the GNU General Public License
@@ -2275,6 +2275,28 @@ static mfcr2_event_t *r2_get_event_bits(struct zt_pvt *p)
 }
 #endif
 
+static int check_for_conference(struct zt_pvt *p)
+{
+	ZT_CONFINFO ci;
+	/* Fine if we already have a master, etc */
+	if (p->master || (p->confno > -1))
+		return 0;
+	memset(&ci, 0, sizeof(ci));
+	if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
+		ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
+		return 0;
+	}
+	/* If we have no master and don't have a confno, then 
+	   if we're in a conference, it's probably a MeetMe room or
+	   some such, so don't let us 3-way out! */
+	if (ci.confno) {
+		if (option_verbose > 2)	
+			ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
+		return 1;
+	}
+	return 0;
+}
+			
 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
 {
 	int res,x;
@@ -2550,7 +2572,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
 						if (p->subs[SUB_REAL].owner->bridge)
 								ast_moh_stop(p->subs[SUB_REAL].owner->bridge);
 					} else if (!p->subs[SUB_THREEWAY].owner) {
-						if (p->threewaycalling) {
+						if (p->threewaycalling && !check_for_conference(p)) {
 							/* XXX This section needs much more error checking!!! XXX */
 							/* Start a 3-way call if feasible */
 							if ((ast->pbx) ||
diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample
index 325cf2e2a2df751d4b7217d16d5eb0f52f9d361d..76e024fffcafc9f94f1df5c13ba0929d78dbce3b 100755
--- a/configs/extensions.conf.sample
+++ b/configs/extensions.conf.sample
@@ -83,7 +83,7 @@ TRUNK=Zap/g2					; Trunk interface
 ; up, please go to www.gnophone.com or www.iaxtel.com
 ;
 [iaxtel700]
-exten => _91700NXXXXXX,1,Dial(IAX/${IAXINFO}@iaxtel.com/${EXTEN-1}@iaxtel)
+exten => _91700NXXXXXX,1,Dial(IAX/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel)
 
 [iaxprovider]
 ;switch => IAX/user:[key]@myserver/mycontext
@@ -92,34 +92,34 @@ exten => _91700NXXXXXX,1,Dial(IAX/${IAXINFO}@iaxtel.com/${EXTEN-1}@iaxtel)
 ;
 ; International long distance through trunk
 ;
-exten => 9011.,1,Dial(${TRUNK}/${EXTEN-1})
+exten => 9011.,1,Dial(${TRUNK}/${EXTEN:1})
 exten => 9011.,2,Congestion
 
 [trunkld]
 ;
 ; Long distance context accessed through trunk
 ;
-exten => _91NXXNXXXXXX,1,Dial(${TRUNK}/${EXTEN-1})
+exten => _91NXXNXXXXXX,1,Dial(${TRUNK}/${EXTEN:1})
 exten => _91NXXNXXXXXX,2,Congestion
 
 [trunklocal]
 ;
 ; Local seven-digit dialing accessed through trunk interface
 ;
-exten => _9NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1})
+exten => _9NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1})
 exten => _9NXXXXXX,2,Congestion
 
 [trunktollfree]
 ;
 ; Long distance context accessed through trunk interface
 ;
-exten => _91800NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1})
+exten => _91800NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1})
 exten => _91800NXXXXXX,2,Congestion
-exten => _91888NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1})
+exten => _91888NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1})
 exten => _91888NXXXXXX,2,Congestion
-exten => _91877NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1})
+exten => _91877NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1})
 exten => _91877NXXXXXX,2,Congestion
-exten => _91866NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1})
+exten => _91866NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1})
 exten => _91866NXXXXXX,2,Congestion
 
 [international]
diff --git a/manager.c b/manager.c
index f7a3b51262dd7f3827e0156ba21f64c67d82724b..a0c06f5a5f259b1c687752e2ac63af2a703097fb 100755
--- a/manager.c
+++ b/manager.c
@@ -30,6 +30,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/options.h>
 #include <asterisk/cli.h>
+#include <asterisk/app.h>
 #include <asterisk/pbx.h>
 
 static int enabled = 0;
@@ -389,6 +390,18 @@ static int action_originate(struct mansession *s, struct message *m)
 	return 0;
 }
 
+static int action_mailboxstatus(struct mansession *s, struct message *m)
+{
+	char *mailbox = get_header(m, "Mailbox");
+	if (!mailbox || !strlen(mailbox)) {
+		send_error(s, "Mailbox not specified");
+		return 0;
+	}
+	send_ack(s, "Mailbox status will follow");
+	manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting:%d\r\n", mailbox, ast_app_has_voicemail(mailbox));
+	return 0;
+}
+
 static int process_message(struct mansession *s, struct message *m)
 {
 	char action[80];
@@ -638,6 +651,7 @@ int init_manager(void)
 		ast_manager_register( "Status", EVENT_FLAG_CALL, action_status, "Status" );
 		ast_manager_register( "Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect" );
 		ast_manager_register( "Originate", EVENT_FLAG_CALL, action_originate, "Originate Call" );
+		ast_manager_register( "MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox" );
 		ast_manager_register( "Command", EVENT_FLAG_COMMAND, action_command, "Execute Command" );
 
 		ast_cli_register(&show_mancmds_cli);
diff --git a/pbx.c b/pbx.c
index d2c7bf90b99b927b5dc2713e908c773f60f63aef..a7ed72064aec4714122c290b67f0af498ea5deef 100755
--- a/pbx.c
+++ b/pbx.c
@@ -710,12 +710,21 @@ static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char *
 					} else if (!strcmp(cp3, "EXTEN")) {
 						*cp4 = c->exten;
 					} else if (!strncmp(cp3, "EXTEN-", strlen("EXTEN-")) && 
+						/* XXX Remove me eventually */
 						(sscanf(cp3 + strlen("EXTEN-"), "%d", &offset) == 1)) {
 						if (offset < 0)
 							offset=0;
 						if (offset > strlen(c->exten))
 							offset = strlen(c->exten);
 						*cp4 = c->exten + offset;
+						ast_log(LOG_WARNING, "The use of 'EXTEN-foo' has been derprecated in favor of 'EXTEN:foo'\n");
+					} else if (!strncmp(cp3, "EXTEN:", strlen("EXTEN:")) && 
+						(sscanf(cp3 + strlen("EXTEN:"), "%d", &offset) == 1)) {
+						if (offset < 0)
+							offset=0;
+						if (offset > strlen(c->exten))
+							offset = strlen(c->exten);
+						*cp4 = c->exten + offset;
 					} else if (!strcmp(cp3, "RDNIS")) {
 						*cp4 = c->rdnis;
 						if (!(*cp4))
@@ -2784,8 +2793,8 @@ int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int pri
 		struct ast_frame *f;
 		tmpchan = ast_channel_alloc(0);
 		if (tmpchan) {
-			ast_setstate(tmpchan, chan->_state);
 			snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name);
+			ast_setstate(tmpchan, chan->_state);
 			/* Make formats okay */
 			tmpchan->readformat = chan->readformat;
 			tmpchan->writeformat = chan->writeformat;