diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample
index 7ff155af7895b3513576f662b867e73c43c7d88f..ecbaa5a6f4d33aee648354eddd41bbd2f728b09b 100755
--- a/configs/extensions.conf.sample
+++ b/configs/extensions.conf.sample
@@ -254,6 +254,12 @@ include => iaxprovider
 ; be substituted in the switch routine itself)
 ;
 ; lswitch => Loopback/12${EXTEN}@othercontext
+;
+; An "eswitch" is like a switch but the evaluation of
+; variable substitution is performed at runtime before
+; being passed to the switch routine.
+;
+; eswitch => IAX2/context@${CURSERVER}
 
 [macro-stdexten];
 ;
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index 33aa1b589a12e6a38075c0bdb472d2eb2c012ab8..1c48b456a711c836a5557a3d8dcb3c795c9f625c 100755
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -424,16 +424,17 @@ int ast_context_verify_includes(struct ast_context *con);
  * \param context context to which to add the switch
  * \param sw switch to add
  * \param data data to pass to switch
+ * \param eval whether to evaluate variables when running switch
  * \param registrar whoever registered the switch
  * This function registers a switch with the asterisk switch architecture
  * It returns 0 on success, -1 on failure
  */
-int ast_context_add_switch(const char *context, const char *sw, const char *data, const char *registrar);
+int ast_context_add_switch(const char *context, const char *sw, const char *data, int eval, const char *registrar);
 //! Adds a switch (first param is a ast_context)
 /*!
  * See ast_context_add_switch()
  */
-int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar);
+int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar);
 
 //! Remove a switch
 /*!
diff --git a/pbx.c b/pbx.c
index 2b506dc9dba68d98c3ed516be982baf0c2a4ee45..fcfbb457853df66020a7b1dfc6be4c309dd4b5a0 100755
--- a/pbx.c
+++ b/pbx.c
@@ -56,6 +56,9 @@
 #define EXT_DATA_SIZE 8192
 #endif
 
+#define SWITCH_DATA_LENGTH 256
+
+
 #define	VAR_NORMAL		1
 #define	VAR_SOFTTRAN	2
 #define	VAR_HARDTRAN	3
@@ -95,7 +98,9 @@ struct ast_sw {
 	char *name;
 	const char *registrar;			/* Registrar */
 	char *data;		/* Data load */
+	int eval;
 	struct ast_sw *next;			/* Link them together */
+	char *tmpdata;
 	char stuff[0];
 };
 
@@ -758,16 +763,19 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan, struct ast
 			sw = tmp->alts;
 			while(sw) {
 				if ((asw = pbx_findswitch(sw->name))) {
+					/* Substitute variables now */
+					if (sw->eval) 
+						pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1);
 					if (action == HELPER_CANMATCH)
-						res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->data) : 0;
+						res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0;
 					else if (action == HELPER_MATCHMORE)
-						res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->data) : 0;
+						res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0;
 					else
-						res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->data) : 0;
+						res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0;
 					if (res) {
 						/* Got a match */
 						*swo = asw;
-						*data = sw->data;
+						*data = sw->eval ? sw->tmpdata : sw->data;
 						*foundcontext = context;
 						return NULL;
 					}
@@ -3612,7 +3620,7 @@ int ast_context_add_include2(struct ast_context *con, const char *value,
  *  EBUSY  - can't lock
  *  ENOENT - no existence of context
  */
-int ast_context_add_switch(const char *context, const char *sw, const char *data, const char *registrar)
+int ast_context_add_switch(const char *context, const char *sw, const char *data, int eval, const char *registrar)
 {
 	struct ast_context *c;
 
@@ -3626,7 +3634,7 @@ int ast_context_add_switch(const char *context, const char *sw, const char *data
 	while (c) {
 		/* ... search for the right one ... */
 		if (!strcmp(ast_get_context_name(c), context)) {
-			int ret = ast_context_add_switch2(c, sw, data, registrar);
+			int ret = ast_context_add_switch2(c, sw, data, eval, registrar);
 			/* ... unlock contexts list and return */
 			ast_unlock_contexts();
 			return ret;
@@ -3648,7 +3656,7 @@ int ast_context_add_switch(const char *context, const char *sw, const char *data
  *  EINVAL - there is no existence of context for inclusion
  */
 int ast_context_add_switch2(struct ast_context *con, const char *value,
-	const char *data, const char *registrar)
+	const char *data, int eval, const char *registrar)
 {
 	struct ast_sw *new_sw;
 	struct ast_sw *i, *il = NULL; /* sw, sw_last */
@@ -3660,6 +3668,11 @@ int ast_context_add_switch2(struct ast_context *con, const char *value,
 	if (data)
 		length += strlen(data);
 	length++;
+	if (eval) {
+		/* Create buffer for evaluation of variables */
+		length += SWITCH_DATA_LENGTH;
+		length++;
+	}
 
 	/* allocate new sw structure ... */
 	if (!(new_sw = malloc(length))) {
@@ -3675,11 +3688,17 @@ int ast_context_add_switch2(struct ast_context *con, const char *value,
 	strcpy(new_sw->name, value);
 	p += strlen(value) + 1;
 	new_sw->data = p;
-	if (data)
+	if (data) {
 		strcpy(new_sw->data, data);
-	else
+		p += strlen(data) + 1;
+	} else {
 		strcpy(new_sw->data, "");
+		p++;
+	}
+	if (eval) 
+		new_sw->tmpdata = p;
 	new_sw->next      = NULL;
+	new_sw->eval	  = eval;
 	new_sw->registrar = registrar;
 
 	/* ... try to lock this context ... */
diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c
index 63c66016cbfbf8581a77f18409076437fd7eb2e9..84420bad402a4a5f7eea01331e5a18311901105f 100755
--- a/pbx/pbx_config.c
+++ b/pbx/pbx_config.c
@@ -1754,7 +1754,7 @@ static int pbx_load_module(void)
 						pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
 						if (ast_context_add_ignorepat2(con, realvalue, registrar))
 							ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
-					} else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch")) {
+					} else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
 						char *stringp=NULL;
 						memset(realvalue, 0, sizeof(realvalue));
 						if (!strcasecmp(v->name, "switch"))
@@ -1767,7 +1767,7 @@ static int pbx_load_module(void)
 						data = strsep(&stringp, "");
 						if (!data)
 							data = "";
-						if (ast_context_add_switch2(con, appl, data, registrar))
+						if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar))
 							ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
 					}
 					v = v->next;