Index: apps/app_queue.c
===================================================================
--- apps/app_queue.c	(revision 25017)
+++ apps/app_queue.c	(working copy)
@@ -237,6 +237,9 @@
 /*! \brief queues.conf [general] option */
 static int autofill_default = 0;
 
+/*! \brief queues.conf [general] option */
+static int montype_default = 0;
+
 enum queue_result {
 	QUEUE_UNKNOWN = 0,
 	QUEUE_TIMEOUT = 1,
@@ -345,6 +348,7 @@
 	int servicelevel;               /*!< seconds setting for servicelevel*/
 	int callscompletedinsl;         /*!< Number of calls answered with servicelevel*/
 	char monfmt[8];                 /*!< Format to use when recording calls */
+	int montype;			/*!< Monitor type  Monitor vs. MixMonitor */
 	char sound_next[80];            /*!< Sound file: "Your call is now first in line" (def. queue-youarenext) */
 	char sound_thereare[80];        /*!< Sound file: "There are currently" (def. queue-thereare) */
 	char sound_calls[80];           /*!< Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
@@ -580,6 +584,7 @@
 	q->servicelevel = 0;
 	q->ringinuse = 1;
 	q->autofill = autofill_default;
+	q->montype = montype_default;
 	q->moh[0] = '\0';
 	q->announce[0] = '\0';
 	q->context[0] = '\0';
@@ -705,6 +710,9 @@
 		q->wrapuptime = atoi(val);
 	} else if (!strcasecmp(param, "autofill")) {
 		q->autofill = ast_true(val);
+	} else if (!strcasecmp(param, "monitor-type")) {
+		if (!strcasecmp(val, "mixmonitor"))
+			q->montype = 1;
 	} else if (!strcasecmp(param, "autopause")) {
 		q->autopause = ast_true(val);
 	} else if (!strcasecmp(param, "maxlen")) {
@@ -1245,9 +1253,8 @@
 			manager_event(EVENT_FLAG_CALL, "Leave",
 				"Channel: %s\r\nQueue: %s\r\nCount: %d\r\n",
 				qe->chan->name, q->name,  q->count);
-#if 0
-ast_log(LOG_NOTICE, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
-#endif
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
 			/* Take us out of the queue */
 			if (prev)
 				prev->next = cur->next;
@@ -2089,6 +2096,15 @@
 	time_t now = time(NULL);
 	struct ast_bridge_config bridge_config;
 	char nondataquality = 1;
+	const char *monitorfilename;
+	const char *monitor_exec;
+	const char *monitor_options;
+	int ret;
+	char tmpid[256], tmpid2[256];
+	char meid[1024], meid2[1024];
+	char mixmonargs[1512];
+	struct ast_app *mixmonapp = NULL;
+	char *p;
 
 	memset(&bridge_config, 0, sizeof(bridge_config));
 	time(&now);
@@ -2274,23 +2290,82 @@
 		}
 		/* Begin Monitoring */
 		if (qe->parent->monfmt && *qe->parent->monfmt) {
-			const char *monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
-			if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
-				which = qe->chan;
-			else
-				which = peer;
-			if (monitorfilename)
-				ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1 );
-			else if (qe->chan->cdr) 
-				ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1 );
-			else {
-				/* Last ditch effort -- no CDR, make up something */
-				char tmpid[256];
-				snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
-				ast_monitor_start(which, qe->parent->monfmt, tmpid, 1 );
+			if (!qe->parent->montype) {
+				if (option_debug)
+					ast_log(LOG_DEBUG, "Starting Monitor as requested.\n");
+				monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
+				if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
+					which = qe->chan;
+				else
+					which = peer;
+				if (monitorfilename)
+					ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1 );
+				else if (qe->chan->cdr) 
+					ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1 );
+				else {
+					/* Last ditch effort -- no CDR, make up something */
+					snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
+					ast_monitor_start(which, qe->parent->monfmt, tmpid, 1 );
+				}
+				if (qe->parent->monjoin)
+					ast_monitor_setjoinfiles(which, 1);
+			} else {
+				if (option_debug)
+					ast_log(LOG_DEBUG, "Starting MixMonitor as requested.\n");
+				monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
+				if (!monitorfilename) {
+					if (qe->chan->cdr)
+						ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid)-1);
+					else 
+						snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
+				} else {
+					ast_copy_string(tmpid2, monitorfilename, sizeof(tmpid2)-1);
+					for (p = tmpid2; *p ; p++) {
+						if (*p == '^' && *(p+1) == '{') {
+							*p = '$';
+						}
+					}
+
+					pbx_substitute_variables_helper(qe->chan, tmpid2, tmpid, sizeof(tmpid) - 1);
+				}
+
+				monitor_exec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC");
+				monitor_options = pbx_builtin_getvar_helper(qe->chan, "MONITOR_OPTIONS");
+
+				if (monitor_exec) {
+					ast_copy_string(meid2, monitor_exec, sizeof(meid2)-1);
+					for (p = meid2; *p ; p++) {
+						if (*p == '^' && *(p+1) == '{') {
+							*p = '$';
+						}
+					}
+					pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
+				} else {
+					monitor_exec = ast_strdupa("");
+				}
+	
+				if (!monitor_options)
+					monitor_options = ast_strdupa("");
+	
+				snprintf(tmpid2, sizeof(tmpid2)-1, "%s.%s", tmpid, qe->parent->monfmt);
+
+				mixmonapp = pbx_findapp("MixMonitor");
+
+				if (mixmonapp) {
+					if (!ast_strlen_zero(monitor_exec)) {
+						snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
+					} else 
+						snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s", tmpid2, monitor_options);
+						
+					if (option_debug)
+						ast_log(LOG_DEBUG, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
+
+					ret = pbx_exec(qe->chan, mixmonapp, mixmonargs);
+
+				} else
+					ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
+
 			}
-			if (qe->parent->monjoin)
-				ast_monitor_setjoinfiles(which, 1);
 		}
 		/* Drop out of the queue at this point, to prepare for next caller */
 		leave_queue(qe);			
@@ -3364,6 +3439,10 @@
 			autofill_default = 0;
 			if ((general_val = ast_variable_retrieve(cfg, "general", "autofill")))
 				autofill_default = ast_true(general_val);
+			montype_default = 0;
+			if ((general_val = ast_variable_retrieve(cfg, "general", "monitor-type")))
+				if (!strcasecmp(general_val, "mixmonitor"))
+					montype_default = 1;
 		} else {	/* Define queue */
 			/* Look for an existing one */
 			AST_LIST_TRAVERSE(&queues, q, list) {
Index: configs/queues.conf.sample
===================================================================
--- configs/queues.conf.sample	(revision 25017)
+++ configs/queues.conf.sample	(working copy)
@@ -28,6 +28,20 @@
 ;
 autofill = yes
 ;
+; Monitor Type
+;    By setting monitor-type = MixMonitor, when specifying monitor-format
+;    to enable recording of queue member conversations, app_queue will
+;    now use the new MixMonitor application instead of Monitor so 
+;    the concept of "joining/mixing" the in/out files now goes away
+;    when this is enabled. You can set the default type for all queues
+;    here, and then also change monitor-type for individual queues within
+;    queue by using the same configuation parameter within a queue 
+;    configuration block. If you do not specify or comment out this option,
+;    it will default to the old 'Monitor' behavior to keep backward
+;    compatibility. 
+;
+monitor-type = MixMonitor
+;
 ; Note that a timeout to fail out of a queue may be passed as part of
 ; an application call from extensions.conf:
 ; Queue(queuename|[options]|[optionalurl]|[announceoverride]|[timeout])
@@ -155,7 +169,7 @@
 			;       ("All reps busy / wait for next")
 ;periodic-announce = queue-periodic-announce
 ;
-; Calls may be recorded using Asterisk's monitor resource
+; Calls may be recorded using Asterisk's monitor/MixMonitor resource
 ; This can be enabled from within the Queue application, starting recording
 ; when the call is actually picked up; thus, only successful calls are
 ; recorded, and you are not recording while people are listening to MOH.
@@ -168,6 +182,19 @@
 ;
 ; monitor-format = gsm|wav|wav49
 ;
+; Monitor Type
+;    By setting monitor-type = MixMonitor, when specifying monitor-format
+;    to enable recording of queue member conversations, app_queue will
+;    now use the new MixMonitor application instead of Monitor so
+;    the concept of "joining/mixing" the in/out files now goes away
+;    when this is enabled. If you do not specify or comment out this option,
+;    it will default to the old 'Monitor' behavior to keep backward
+;    compatibility.
+;
+; monitor-type = MixMonitor
+;
+; ----------------------- TYPE MONITOR OPTIONS --------------------------------
+;
 ; If you wish to have the two files joined together when the call ends, set this
 ; to yes.
 ;
@@ -181,6 +208,30 @@
 ; strict - callers cannot join a queue with no members or only unavailable
 ;          members
 ;
+; ----------------------- TYPE MIXMONITOR OPTIONS -----------------------------
+;
+;
+; You can specify the options supplied to MixMonitor by calling
+;   Set(MONITOR_OPTIONS=av(<x>)V(<x>)W(<x>))
+; The 'b' option for MixMonitor (only save audio to the file while bridged) is 
+; implied.
+;
+; You can specify a post recording command to be executed after the end of
+; recording by calling
+;   Set(MONITOR_EXEC=mv /var/spool/asterisk/monitor/^{MONITOR_FILENAME} /tmp/^{MONITOR_FILENAME})
+;
+; The command specified within the contents of MONITOR_EXEC will be executed when
+; the recording is over. Any strings matching ^{X} will be unescaped to ${X} and
+; all variables will be evaluated just prior to recording being started.
+;
+; The contents of MONITOR_FILENAME will also be unescaped from ^{X} to ${X} and
+; all variables will be evaluated just prior to recording being started.
+;
+;
+;
+;
+;
+;
 ; joinempty = yes
 ;
 ; If you wish to remove callers from the queue when new callers cannot join,
