#
#
# patch "configs/extensions.lua.sample"
#  from [4523db406f6eb211766aae3416330e5e6920f4d2]
#    to [40f773853160d04fbff2c18f11b827cd0f15b53c]
# 
# patch "pbx/pbx_lua.c"
#  from [e7e9d2c3e980bd974a77f47fbaae2776603fb3dc]
#    to [7cf313ede53c80849a24ad27ff466409c47a0a1f]
#
============================================================
--- configs/extensions.lua.sample	4523db406f6eb211766aae3416330e5e6920f4d2
+++ configs/extensions.lua.sample	40f773853160d04fbff2c18f11b827cd0f15b53c
@@ -18,15 +18,6 @@ TRUNKMSD = 1
 -- representing a context.  Extensions are defined in each context.  See below
 -- for examples.
 --
--- This file can be automatically included in the extensions.conf file using
--- the 'utils/build-extensions-conf.lua' script and a #exec statement in
--- extensions.conf.
---
---   #exec /usr/bin/utils/build-extensions.conf.lua -c
--- 
--- The 'execincludes' option must be set to 'yes' in the [options] section of
--- asterisk.conf for this to work properly.
--- 
 -- Extension names may be numbers, letters, or combinations thereof. If
 -- an extension name is prefixed by a '_' character, it is interpreted as
 -- a pattern rather than a literal.  In patterns, some characters have
============================================================
--- pbx/pbx_lua.c	e7e9d2c3e980bd974a77f47fbaae2776603fb3dc
+++ pbx/pbx_lua.c	7cf313ede53c80849a24ad27ff466409c47a0a1f
@@ -40,12 +40,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi
 #include "asterisk/utils.h"
 #include "asterisk/term.h"
 #include "asterisk/paths.h"
+#include "asterisk/hashtab.h"
 
 #include <lua5.1/lua.h>
 #include <lua5.1/lauxlib.h>
 #include <lua5.1/lualib.h>
 
 static char *config = "extensions.lua";
+static char *registrar = "pbx_lua";
 
 #define LUA_EXT_DATA_SIZE 256
 #define LUA_BUF_SIZE 4096
@@ -55,6 +57,7 @@ static int lua_sort_extensions(lua_State
 static int lua_reload_extensions(lua_State *L);
 static void lua_free_extensions(void);
 static int lua_sort_extensions(lua_State *L);
+static int lua_register_switches(lua_State *L);
 static int lua_extension_cmp(lua_State *L);
 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
 static int lua_pbx_findapp(lua_State *L);
@@ -92,6 +95,9 @@ long config_file_size = 0;
 char *config_file_data = NULL;
 long config_file_size = 0;
 
+static struct ast_context *local_contexts = NULL;
+static struct ast_hashtab *local_table = NULL;
+
 static const struct ast_datastore_info lua_datastore = {
 	.type = "lua",
 	.destroy = lua_state_destroy,
@@ -789,6 +795,65 @@ static int lua_sort_extensions(lua_State
 }
 
 /*!
+ * \brief Register dialplan switches for our pbx_lua contexs.
+ *
+ * In the event of an error, an error string will be pushed onto the lua stack.
+ *
+ * \retval 0 success
+ * \retval 1 failure
+ */
+static int lua_register_switches(lua_State *L)
+{
+	int extensions;
+	struct ast_context *con = NULL;
+
+	/* create the hash table for our contexts */
+	/* XXX do we ever need to destroy this? pbx_config does not */
+	if (!local_table)
+		local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
+
+	/* load the 'extensions' table */
+	lua_getglobal(L, "extensions");
+	extensions = lua_gettop(L);
+	if (lua_isnil(L, -1)) {
+		lua_pop(L, 1);
+		lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
+		return 1;
+	}
+
+	/* iterate through the extensions table and register a context and
+	 * dialplan switch for each lua context
+	 */
+	for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
+		int context = lua_gettop(L);
+		int context_name = context - 1;
+		const char *context_str = lua_tostring(L, context_name);
+
+		/* find or create this context */
+		con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
+		if (!con) {
+			/* remove extensions table and context key and value */
+			lua_pop(L, 3);
+			lua_pushstring(L, "Failed to find or create context\n");
+			return 1;
+		}
+
+		/* register the switch */
+		if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) {
+			/* remove extensions table and context key and value */
+			lua_pop(L, 3);
+			lua_pushstring(L, "Unable to create switch for context\n");
+			return 1;
+		}
+	}
+	
+	/* remove the extensions table */
+	lua_pop(L, 1);
+	return 0;
+}
+
+
+/*!
  * \brief [lua_CFunction] Compare two extensions (for access from lua, don't
  * call directly)
  *
@@ -852,7 +917,8 @@ static char *lua_read_extensions_file(lu
 
 	if (luaL_loadbuffer(L, data, *size, "extensions.lua")
 			|| lua_pcall(L, 0, LUA_MULTRET, 0)
-			|| lua_sort_extensions(L)) {
+			|| lua_sort_extensions(L)
+			|| lua_register_switches(L)) {
 		ast_free(data);
 		data = NULL;
 		*size = 0;
@@ -933,6 +999,11 @@ static int lua_reload_extensions(lua_Sta
 
 	config_file_data = data;
 	config_file_size = size;
+	
+	/* merge our new contexts */
+	ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
+	local_table = NULL;
+	local_contexts = NULL;
 
 	ast_mutex_unlock(&config_file_lock);
 	return 0;
@@ -1323,6 +1394,14 @@ static int unload_module(void)
 
 static int unload_module(void)
 {
+	if (!local_table)
+		local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
+
+	/* do an empty merge to clean up */
+	ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
+	local_table = NULL;
+	local_contexts = NULL;
+
 	ast_unregister_switch(&lua_switch);
 	lua_free_extensions();
 	return 0;
