diff --git a/pbx/Makefile b/pbx/Makefile
index 3bb8d33cf65c8665e336619bd2a37eaf638ca5c6..28ca0e0b423f932e9c11b1a3110b4513f503b27f 100755
--- a/pbx/Makefile
+++ b/pbx/Makefile
@@ -13,7 +13,7 @@
 
 
 
-PBX_LIBS=pbx_config.so pbx_spool.so pbx_dundi.so  pbx_loopback.so
+PBX_LIBS=pbx_config.so pbx_spool.so pbx_dundi.so pbx_loopback.so pbx_realtime.so
 
 # Add GTK console if appropriate
 #PBX_LIBS+=$(shell gtk-config --cflags >/dev/null 2>/dev/null && echo "pbx_gtkconsole.so")
diff --git a/pbx/pbx_realtime.c b/pbx/pbx_realtime.c
new file mode 100755
index 0000000000000000000000000000000000000000..6b1e6304cc02587cd23d7609641ff4074a6024f8
--- /dev/null
+++ b/pbx/pbx_realtime.c
@@ -0,0 +1,181 @@
+/*
+ * Realtime PBX Module
+ *
+ * Copyright (C) 2004, Digium Inc.
+ *
+ * Written by Mark Spencer <markster@digium.com>
+ *
+ * This program is Free Software distributed under the terms of
+ * of the GNU General Public License.
+ */
+
+#include <asterisk/file.h>
+#include <asterisk/logger.h>
+#include <asterisk/channel.h>
+#include <asterisk/config.h>
+#include <asterisk/options.h>
+#include <asterisk/pbx.h>
+#include <asterisk/module.h>
+#include <asterisk/frame.h>
+#include <asterisk/file.h>
+#include <asterisk/cli.h>
+#include <asterisk/lock.h>
+#include <asterisk/md5.h>
+#include <asterisk/linkedlists.h>
+#include <asterisk/chanvars.h>
+#include <asterisk/sched.h>
+#include <asterisk/io.h>
+#include <asterisk/utils.h>
+#include <asterisk/crypto.h>
+#include <asterisk/astdb.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+static char *tdesc = "Realtime Switch";
+
+/* Realtime switch looks up extensions in the supplied realtime table.
+
+	[context@][realtimetable][/options]
+
+	If the realtimetable is omitted it is assumed to be "extensions".  If no context is 
+	specified the context is assumed to be whatever is the container.
+
+	The realtime table should have entries for context,exten,priority,app,args
+	
+	The realtime table currently does not support patterns or callerid fields.
+
+*/
+
+
+#define REALTIME_COMMON \
+	char *buf; \
+	char *opts; \
+	const char *cxt; \
+	char *table; \
+	int res=-1; \
+	struct ast_variable *var; \
+	buf = ast_strdupa(data); \
+	if (buf) { \
+		opts = strchr(buf, '/'); \
+		if (opts) { \
+			*opts='\0'; \
+			opts++; \
+		} else \
+			opts=""; \
+		table = strchr(buf, '@'); \
+		if (table) { \
+			*table = '\0'; \
+			table++;\
+			cxt = buf; \
+		} else cxt = NULL; \
+		if (!cxt || ast_strlen_zero(cxt)) \
+			cxt = context;\
+		if (!table || ast_strlen_zero(table)) \
+			table = "extensions"; \
+		var = realtime_switch_common(table, cxt, exten, priority); \
+	} else \
+		return -1; 
+
+static struct ast_variable *realtime_switch_common(const char *table, const char *context, const char *exten, int priority)
+{
+	struct ast_variable *var;
+	char pri[20];
+	snprintf(pri, sizeof(pri), "%d", priority);
+	printf("%s/%s/%s/%s exists\n", table, context, exten, pri);
+	var = ast_load_realtime(table, "context", context, "exten", exten, "priority", pri, NULL);
+	return var;
+}
+
+static int realtime_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
+{
+	REALTIME_COMMON;
+	if (var) ast_destroy_realtime(var);
+	if (var)
+		res = 1;
+	return res > 0 ? res : 0;
+}
+
+static int realtime_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
+{
+	REALTIME_COMMON;
+	if (var) ast_destroy_realtime(var);
+	if (var)
+		res = 1;
+	return res;
+}
+
+static int realtime_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
+{
+	char app[256];
+	char *appdata="";
+	struct ast_app *a;
+	struct ast_variable *v;
+	REALTIME_COMMON;
+	if (var) {
+		v = var;
+		while(v) {
+			if (!strcasecmp(v->name, "app"))
+				strncpy(app, v->value, sizeof(app) -1 );
+			else if (!strcasecmp(v->name, "appdata"))
+				appdata = ast_strdupa(v->value);
+			v = v->next;
+		}
+		if (!ast_strlen_zero(app)) {
+			a = pbx_findapp(app);
+			if (a) {
+				res = pbx_exec(chan, a, appdata, newstack);
+			} else
+				ast_log(LOG_NOTICE, "No such application '%s' for extension '%s' in context '%s'\n", app, exten, context);
+		}
+		ast_destroy_realtime(var);
+	}
+	return res;
+}
+
+static int realtime_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
+{
+	REALTIME_COMMON;
+	if (var) ast_destroy_realtime(var);
+	return res;
+}
+
+static struct ast_switch realtime_switch =
+{
+        name:                   "Realtime",
+        description:    		"Realtime Dialplan Switch",
+        exists:                 realtime_exists,
+        canmatch:               realtime_canmatch,
+        exec:                   realtime_exec,
+        matchmore:              realtime_matchmore,
+};
+
+char *description(void)
+{
+	return tdesc;
+}
+
+int usecount(void)
+{
+	return 1;
+}
+
+char *key()
+{
+	return ASTERISK_GPL_KEY;
+}
+
+int unload_module(void)
+{
+	ast_unregister_switch(&realtime_switch);
+	return 0;
+}
+
+int load_module(void)
+{
+	ast_register_switch(&realtime_switch);
+	return 0;
+}
+