Index: apps/app_queue.c
===================================================================
--- apps/app_queue.c	(revision 46843)
+++ apps/app_queue.c	(working copy)
@@ -338,6 +338,7 @@
 /* values used in multi-bit flags in call_queue */
 #define QUEUE_EMPTY_NORMAL 1
 #define QUEUE_EMPTY_STRICT 2
+#define QUEUE_EMPTY_LOOSE 3
 #define ANNOUNCEHOLDTIME_ALWAYS 1
 #define ANNOUNCEHOLDTIME_ONCE 2
 #define QUEUE_EVENT_VARIABLES 3
@@ -488,6 +489,7 @@
 enum queue_member_status {
 	QUEUE_NO_MEMBERS,
 	QUEUE_NO_REACHABLE_MEMBERS,
+	QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS,
 	QUEUE_NORMAL
 };
 
@@ -501,18 +503,23 @@
 		if (max_penalty && (member->penalty > max_penalty))
 			continue;
 
-		if (member->paused) continue;
-
 		switch (member->status) {
 		case AST_DEVICE_INVALID:
 			/* nothing to do */
 			break;
 		case AST_DEVICE_UNAVAILABLE:
-			result = QUEUE_NO_REACHABLE_MEMBERS;
+			if (result != QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS) 
+				result = QUEUE_NO_REACHABLE_MEMBERS;
 			break;
 		default:
 			ast_mutex_unlock(&q->lock);
-			return QUEUE_NORMAL;
+			if (member->paused) 
+			{
+				result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
+			} else {
+				return QUEUE_NORMAL;
+			}
+			break;
 		}
 	}
 	
@@ -903,6 +910,8 @@
 			q->strategy = QUEUE_STRATEGY_RINGALL;
 		}
 	} else if (!strcasecmp(param, "joinempty")) {
+		if (!strcasecmp(val, "loose"))
+			q->joinempty = QUEUE_EMPTY_LOOSE;
 		if (!strcasecmp(val, "strict"))
 			q->joinempty = QUEUE_EMPTY_STRICT;
 		else if (ast_true(val))
@@ -910,6 +919,8 @@
 		else
 			q->joinempty = 0;
 	} else if (!strcasecmp(param, "leavewhenempty")) {
+		if (!strcasecmp(val, "loose"))
+			q->leavewhenempty = QUEUE_EMPTY_LOOSE;
 		if (!strcasecmp(val, "strict"))
 			q->leavewhenempty = QUEUE_EMPTY_STRICT;
 		else if (ast_true(val))
@@ -1189,8 +1200,10 @@
 	stat = get_member_status(q, qe->max_penalty);
 	if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
 		*reason = QUEUE_JOINEMPTY;
-	else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
+	else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS))
 		*reason = QUEUE_JOINUNAVAIL;
+	else if ((q->joinempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
+		*reason = QUEUE_JOINUNAVAIL;
 	else if (q->maxlen && (q->count >= q->maxlen))
 		*reason = QUEUE_FULL;
 	else {
@@ -2207,12 +2220,18 @@
 		}
 
 		/* leave the queue if no reachable agents, if enabled */
-		if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
+		if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
 			*reason = QUEUE_LEAVEUNAVAIL;
 			ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
 			leave_queue(qe);
 			break;
 		}
+		if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
+			*reason = QUEUE_LEAVEUNAVAIL;
+			ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
+			leave_queue(qe);
+			break;
+		}
 
 		/* Make a position announcement, if enabled */
 		if (qe->parent->announcefrequency && !ringing &&
@@ -3531,12 +3550,18 @@
 				}
 
 				/* leave the queue if no reachable agents, if enabled */
-				if ((qe.parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
+				if ((qe.parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
 					record_abandoned(&qe);
 					reason = QUEUE_LEAVEUNAVAIL;
 					res = 0;
 					break;
 				}
+				if ((qe.parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
+					record_abandoned(&qe);
+					reason = QUEUE_LEAVEUNAVAIL;
+					res = 0;
+					break;
+				}
 
 				/* Leave if we have exceeded our queuetimeout */
 				if (qe.expire && (time(NULL) > qe.expire)) {
Index: configs/queues.conf.sample
===================================================================
--- configs/queues.conf.sample	(revision 46843)
+++ configs/queues.conf.sample	(working copy)
@@ -254,6 +254,8 @@
 ; no     - callers cannot join a queue with no members
 ; strict - callers cannot join a queue with no members or only unavailable
 ;          members
+; loose  - same as strict, but paused queue members do not count as unavailable
+;          
 ;
 ; ----------------------- TYPE MIXMONITOR OPTIONS -----------------------------
 ;
