diff --git a/agi/DialAnMp3.agi b/agi/DialAnMp3.agi
new file mode 100755
index 0000000000000000000000000000000000000000..59a54265e630bfda974a37075077f3b4865d7091
--- /dev/null
+++ b/agi/DialAnMp3.agi
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+#
+# Simple AGI application to play mp3's selected by a user both using 
+# xmms and over the phone itself.
+#
+$|=1;
+while(<STDIN>) {
+	chomp;
+	last unless length($_);
+	if (/^agi_(\w+)\:\s+(.*)$/) {
+		$AGI{$1} = $2;
+	}
+}
+
+print STDERR "AGI Environment Dump:\n";
+foreach $i (sort keys %AGI) {
+	print STDERR " -- $i = $AGI{$i}\n";
+}
+
+dbmopen(%DIGITS, "/var/lib/asterisk/mp3list", 0644) || die("Unable to open mp3list");;
+
+sub checkresult {
+	my ($res) = @_;
+	my $retval;
+	$tests++;
+	chomp $res;
+	if ($res =~ /^200/) {
+		$res =~ /result=(-?[\w\*\#]+)/;
+		return $1;
+	} else {
+		return -1;
+	}
+}
+
+#print STDERR "1.  Playing beep...\n";
+#print "STREAM FILE beep \"\"\n";
+#$result = <STDIN>;
+#checkresult($result);
+
+print STDERR "2.  Getting song name...\n";
+print "GET DATA demo-enterkeywords\n";
+$result = <STDIN>;
+$digitstr = checkresult($result);
+if ($digitstr < 0) {
+	exit(1);
+}
+$digitstr =~ s/\*/ /g;
+
+print STDERR "Resulting songname is $digitstr\n";
+@searchwords = split (/\s+/, $digitstr);
+print STDERR "Searchwords: " . join(':', @searchwords) . "\n";
+
+foreach $key (sort keys %DIGITS) {
+	@words = split(/\s+/, $DIGITS{$key});
+	$match = 1;
+	foreach $search (@searchwords) {
+		$match = 0 unless grep(/$search/, @words);
+	}
+	if ($match > 0) {
+		print STDERR "File $key matches\n";
+		# Play a beep
+		print "STREAM FILE beep \"\"\n";
+		system("xmms", $key);
+		$result = <STDIN>;
+		if (&checkresult($result) < 0) {
+			exit 0;
+		}
+		print "EXEC MP3Player \"$key\"\n";
+#		print "WAIT FOR DIGIT 60000\n";
+		$result = <STDIN>;
+		if (&checkresult($result) < 0) {
+			exit 0;
+		}
+		print STDERR "Got here...\n";
+	}
+}
+
+print STDERR "4.  Testing 'saynumber' of $digitstr...\n";
+print "STREAM FILE demo-nomatch\"\"\n";
+$result = <STDIN>;
+checkresult($result);
+
diff --git a/agi/numeralize b/agi/numeralize
new file mode 100755
index 0000000000000000000000000000000000000000..5ca51913da429354fee01db11ac54a921289ada9
--- /dev/null
+++ b/agi/numeralize
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+#
+# Build a database linking filenames to their numerical representations
+# using a keypad for the DialAnMp3 application
+#
+
+$mp3dir="/usr/media/mpeg3";
+
+dbmopen(%DIGITS, "/var/lib/asterisk/mp3list", 0644) || die("Unable to open mp3list");;
+sub process_dir {
+	my ($dir) = @_;
+	my $file;
+	my $digits;
+	my @entries;
+	opendir(DIR, $dir);
+	@entries = readdir(DIR);
+	closedir(DIR);
+	foreach $_ (@entries) {
+		if (!/^\./) {
+			$file = "$dir/$_";
+			if (-d "$file") {
+				process_dir("$file");
+			} else {
+				$digits = $_;
+				$digits =~ s/[^ \w]+//g;
+				$digits =~ s/\_/ /g;
+				$digits =~ tr/[a-z]/[A-Z]/;
+				$digits =~ tr/[A-C]/2/;
+				$digits =~ tr/[D-F]/3/;
+				$digits =~ tr/[G-I]/4/;
+				$digits =~ tr/[J-L]/5/;
+				$digits =~ tr/[M-O]/6/;
+				$digits =~ tr/[P-S]/7/;
+				$digits =~ tr/[T-V]/8/;
+				$digits =~ tr/[W-Z]/9/;
+				$digits =~ s/\s+/ /;
+				print "File: $file, digits: $digits\n";
+				$DIGITS{$file} = $digits;
+			}
+		}
+	}
+}
+
+process_dir($mp3dir);
diff --git a/apps/app_agi.c b/apps/app_agi.c
index 91ca9749f81a0a6cac510ccbd82a0382cf41704b..e7bccedf62ffa2eafe8f5c0577f12e7e98c70d3a 100755
--- a/apps/app_agi.c
+++ b/apps/app_agi.c
@@ -352,14 +352,14 @@ int ast_app_getdata(struct ast_channel *c, char *prompt, char *s, int maxlen, in
 static int handle_getdata(struct ast_channel *chan, int fd, int argc, char *argv[])
 {
 	int res;
-	char data[50];
+	char data[1024];
 	int max;
 	int timeout;
 
 	if (argc < 3)
 		return RESULT_SHOWUSAGE;
 	if (argc >= 4) timeout = atoi(argv[3]); else timeout = 0;
-	if (argc >= 5) max = atoi(argv[4]); else max = 50;
+	if (argc >= 5) max = atoi(argv[4]); else max = 1024;
 	res = ast_app_getdata(chan, argv[2], data, max, timeout);
 	if (res == 1)
 		fdprintf(fd, "200 result=%s (timeout)\n", data);
diff --git a/channel.c b/channel.c
index 83659c07342958dad1bed16c5f86427de8d9e439..e75f74723a85593a4ab816d072d5a89ffbd66f88 100755
--- a/channel.c
+++ b/channel.c
@@ -967,7 +967,8 @@ struct ast_frame *ast_read(struct ast_channel *chan)
 		if (!(f->subclass & chan->nativeformats)) {
 			/* This frame can't be from the current native formats -- drop it on the
 			   floor */
-			ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s since our native format has changed\n", chan->name);
+			ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %d since our native format has changed to %d\n", chan->name, f->subclass, chan->nativeformats);
+			ast_frfree(f);
 			f = &null_frame;
 		} else if (chan->pvt->readtrans) {
 			f = ast_translate(chan->pvt->readtrans, f, 1);
diff --git a/channels/chan_iax.c b/channels/chan_iax.c
index ce896c7385c89b44920aba37ffed2bc1f3fbf7ff..d48b24f552eb55550d7d0b329d9c1d5aef3c9bb3 100755
--- a/channels/chan_iax.c
+++ b/channels/chan_iax.c
@@ -1758,6 +1758,10 @@ static int iax_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
 				ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
 			return -2;
 		}
+		if (c0->nativeformats != c1->nativeformats) {
+			ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs, can't native bridge...\n");
+			return -2;
+		}
 		if (!transferstarted) {
 			/* Try the transfer */
 			if (iax_start_transfer(c0, c1))
@@ -2240,12 +2244,13 @@ static int iax_show_channels(int fd, int argc, char *argv[])
 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %s\n"
 #define FORMAT  "%-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %d\n"
 	int x;
+	int numchans = 0;
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
 	ast_cli(fd, FORMAT2, "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "Format");
 	for (x=0;x<AST_IAX_MAX_CALLS;x++) {
 		ast_pthread_mutex_lock(&iaxsl[x]);
-		if (iaxs[x]) 
+		if (iaxs[x]) {
 			ast_cli(fd, FORMAT, inet_ntoa(iaxs[x]->addr.sin_addr), 
 						strlen(iaxs[x]->username) ? iaxs[x]->username : "(None)", 
 						iaxs[x]->callno, iaxs[x]->peercallno, 
@@ -2253,8 +2258,11 @@ static int iax_show_channels(int fd, int argc, char *argv[])
 						iaxs[x]->lag,
 						iaxs[x]->jitter,
 						iaxs[x]->voiceformat);
+			numchans++;
+		}
 		ast_pthread_mutex_unlock(&iaxsl[x]);
 	}
+	ast_cli(fd, "%d active IAX channel(s)\n", numchans);
 	return RESULT_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 93d87773492633e183676cc3bbe59d4668c1ba5e..2d49f1365533ae6d29a8617dcbbb35aae860d444 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -2413,6 +2413,7 @@ static int sip_show_channels(int fd, int argc, char *argv[])
 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %s\n"
 #define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %d\n"
 	struct sip_pvt *cur;
+	int numchans = 0;
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
 	ast_pthread_mutex_lock(&iflock);
@@ -2427,8 +2428,10 @@ static int sip_show_channels(int fd, int argc, char *argv[])
 						0,
 						cur->owner ? cur->owner->nativeformats : 0);
 		cur = cur->next;
+		numchans++;
 	}
 	ast_pthread_mutex_unlock(&iflock);
+	ast_cli(fd, "%d active SIP channel(s)\n", numchans);
 	return RESULT_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
@@ -3048,9 +3051,12 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
 		else
 			transmit_response(p, "202 Accepted", req);
 		ast_log(LOG_DEBUG,"202 Accepted\n");
-		transfer_to = c->bridge;
-		if (transfer_to)
-			ast_async_goto(transfer_to,"", p->refer_to,1, 1);
+		c = p->owner;
+		if (c) {
+			transfer_to = c->bridge;
+			if (transfer_to)
+				ast_async_goto(transfer_to,"", p->refer_to,1, 1);
+		}
 			
 	} 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 45f6aed81340f49c6e99c4bf6a8807f0eaa36874..9e8c9c0286c4cef13771bf8f99bdd4f1719fea88 100755
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -5361,11 +5361,11 @@ static void *pri_dchannel(void *vpri)
 						ast_log(LOG_WARNING, "Ringing requested on channel %d not in use on span %d\n", e->ringing.channel, pri->span);
 						chan = 0;
 					} else if (!strlen(pri->pvt[chan]->dop.dialstr)) {
+						zt_enable_ec(pri->pvt[chan]);
 						pri->pvt[chan]->subs[SUB_REAL].needringing =1;
 					} else
 						ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
 				}
-				zt_enable_ec(pri->pvt[chan]);
 				break;				
 			case PRI_EVENT_FACNAME:
 				chan = e->facname.channel;
diff --git a/configs/parking.conf.sample b/configs/parking.conf.sample
index 54658c9670af0879b144f4afbb7bb685fd93ff3d..20eb427474e920a3a5ae96e6a3b034ec64884a05 100755
--- a/configs/parking.conf.sample
+++ b/configs/parking.conf.sample
@@ -6,4 +6,4 @@
 parkext => 700				; What ext. to dial to park
 parkpos => 701-720			; What extensions to park calls on
 context => parkedcalls			; Which context parked calls are in
-
+;parkingtime => 45			; Number of seconds a call can be parked for (default is 45 seconds)
diff --git a/pbx.c b/pbx.c
index ba3d2bcb04bb41084011ff4185c87fc2585771ee..6e0f073b23c1c014c351d4df7764686f4fe6f028 100755
--- a/pbx.c
+++ b/pbx.c
@@ -1139,7 +1139,7 @@ int ast_pbx_run(struct ast_channel *c)
 				/* Something bad happened, or a hangup has been requested. */
 				if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F'))) {
 					ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
-					exten[pos++] = res;
+					exten[pos++] = digit = res;
 					break;
 				}
 				switch(res) {
diff --git a/sounds/demo-enterkeywords.gsm b/sounds/demo-enterkeywords.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..dafd7a7d947c15a38d093c538b91c21e1b87aede
Binary files /dev/null and b/sounds/demo-enterkeywords.gsm differ
diff --git a/sounds/demo-nomatch.gsm b/sounds/demo-nomatch.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..a869457e58b2723603b9cd0a1638f389537541c6
Binary files /dev/null and b/sounds/demo-nomatch.gsm differ