diff --git a/app.c b/app.c
index 16b20dec9a2ca293b20619d8b9047a785f379c68..5e82418f19afe2f5ee3a52b85b8943c7466c912a 100755
--- a/app.c
+++ b/app.c
@@ -150,121 +150,46 @@ int ast_app_getvoice(struct ast_channel *c, char *dest, char *dstfmt, char *prom
 	return 0;
 }
 
+static int (*ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL;
+static int (*ast_messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL;
+
+void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
+			      int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs))
+{
+	ast_has_voicemail_func = has_voicemail_func;
+	ast_messagecount_func = messagecount_func;
+}
+
+void ast_uninstall_vm_functions(void)
+{
+	ast_has_voicemail_func = NULL;
+	ast_messagecount_func = NULL;
+}
+
 int ast_app_has_voicemail(const char *mailbox, const char *folder)
 {
-	DIR *dir;
-	struct dirent *de;
-	char fn[256];
-	char tmp[256]="";
-	char *mb, *cur;
-	char *context;
-	int ret;
-	if (!folder)
-		folder = "INBOX";
-	/* If no mailbox, return immediately */
-	if (ast_strlen_zero(mailbox))
-		return 0;
-	if (strchr(mailbox, ',')) {
-		strncpy(tmp, mailbox, sizeof(tmp) - 1);
-		mb = tmp;
-		ret = 0;
-		while((cur = strsep(&mb, ","))) {
-			if (!ast_strlen_zero(cur)) {
-				if (ast_app_has_voicemail(cur, folder))
-					return 1; 
-			}
-		}
-		return 0;
-	}
-	strncpy(tmp, mailbox, sizeof(tmp) - 1);
-	context = strchr(tmp, '@');
-	if (context) {
-		*context = '\0';
-		context++;
-	} else
-		context = "default";
-	snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, tmp, folder);
-	dir = opendir(fn);
-	if (!dir)
-		return 0;
-	while ((de = readdir(dir))) {
-		if (!strncasecmp(de->d_name, "msg", 3))
-			break;
-	}
-	closedir(dir);
-	if (de)
-		return 1;
+	if (ast_has_voicemail_func)
+		return ast_has_voicemail_func(mailbox, folder);
+
+        if (option_verbose > 2)
+                ast_verbose(VERBOSE_PREFIX_3 "Message check requested for mailbox %s/folder %s but voicemail not loaded.", mailbox, folder);
+
 	return 0;
 }
 
+
 int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
 {
-	DIR *dir;
-	struct dirent *de;
-	char fn[256];
-	char tmp[256]="";
-	char *mb, *cur;
-	char *context;
-	int ret;
 	if (newmsgs)
 		*newmsgs = 0;
 	if (oldmsgs)
 		*oldmsgs = 0;
-	/* If no mailbox, return immediately */
-	if (ast_strlen_zero(mailbox))
-		return 0;
-	if (strchr(mailbox, ',')) {
-		int tmpnew, tmpold;
-		strncpy(tmp, mailbox, sizeof(tmp) - 1);
-		mb = tmp;
-		ret = 0;
-		while((cur = strsep(&mb, ", "))) {
-			if (!ast_strlen_zero(cur)) {
-				if (ast_app_messagecount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
-					return -1;
-				else {
-					if (newmsgs)
-						*newmsgs += tmpnew; 
-					if (oldmsgs)
-						*oldmsgs += tmpold;
-				}
-			}
-		}
-		return 0;
-	}
-	strncpy(tmp, mailbox, sizeof(tmp) - 1);
-	context = strchr(tmp, '@');
-	if (context) {
-		*context = '\0';
-		context++;
-	} else
-		context = "default";
-	if (newmsgs) {
-		snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, context, tmp);
-		dir = opendir(fn);
-		if (dir) {
-			while ((de = readdir(dir))) {
-				if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
-					!strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
-						(*newmsgs)++;
-					
-			}
-			closedir(dir);
-		}
-	}
-	if (oldmsgs) {
-		snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/Old", (char *)ast_config_AST_SPOOL_DIR, context, tmp);
-		dir = opendir(fn);
-		if (dir) {
-			while ((de = readdir(dir))) {
-				if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
-					!strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
-						(*oldmsgs)++;
-					
-			}
-			closedir(dir);
-		}
-	}
+	if (ast_messagecount_func)
+		return ast_messagecount_func(mailbox, newmsgs, oldmsgs);
+
+        if (option_verbose > 2)
+                ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s but voicemail not loaded.", mailbox);
+
 	return 0;
 }
 
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 7bd2661f44e679a5eb6a467a6141651c142b617c..c253b3e98f1c4598b870bf2219d76810d966bf7e 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -955,6 +955,7 @@ yuck:
 	return x;
 }
 
+
 static int count_messages(char *dir)
 {
 	return last_message_index(dir) + 1;
@@ -1251,6 +1252,7 @@ yuck:
 }
 
 #else
+
 static int count_messages(char *dir)
 {
 	/* Find all .txt files - even if they are not in sequence from 0000 */
@@ -1839,6 +1841,124 @@ static char *mbox(int id)
 	}
 }
 
+static int has_voicemail(const char *mailbox, const char *folder)
+{
+	DIR *dir;
+	struct dirent *de;
+	char fn[256];
+	char tmp[256]="";
+	char *mb, *cur;
+	char *context;
+	int ret;
+	if (!folder)
+		folder = "INBOX";
+	/* If no mailbox, return immediately */
+	if (ast_strlen_zero(mailbox))
+		return 0;
+	if (strchr(mailbox, ',')) {
+		strncpy(tmp, mailbox, sizeof(tmp) - 1);
+		mb = tmp;
+		ret = 0;
+		while((cur = strsep(&mb, ","))) {
+			if (!ast_strlen_zero(cur)) {
+				if (has_voicemail(cur, folder))
+					return 1; 
+			}
+		}
+		return 0;
+	}
+	strncpy(tmp, mailbox, sizeof(tmp) - 1);
+	context = strchr(tmp, '@');
+	if (context) {
+		*context = '\0';
+		context++;
+	} else
+		context = "default";
+	snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, tmp, folder);
+	dir = opendir(fn);
+	if (!dir)
+		return 0;
+	while ((de = readdir(dir))) {
+		if (!strncasecmp(de->d_name, "msg", 3))
+			break;
+	}
+	closedir(dir);
+	if (de)
+		return 1;
+	return 0;
+}
+
+static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
+{
+	DIR *dir;
+	struct dirent *de;
+	char fn[256];
+	char tmp[256]="";
+	char *mb, *cur;
+	char *context;
+	int ret;
+	if (newmsgs)
+		*newmsgs = 0;
+	if (oldmsgs)
+		*oldmsgs = 0;
+	/* If no mailbox, return immediately */
+	if (ast_strlen_zero(mailbox))
+		return 0;
+	if (strchr(mailbox, ',')) {
+		int tmpnew, tmpold;
+		strncpy(tmp, mailbox, sizeof(tmp) - 1);
+		mb = tmp;
+		ret = 0;
+		while((cur = strsep(&mb, ", "))) {
+			if (!ast_strlen_zero(cur)) {
+				if (messagecount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
+					return -1;
+				else {
+					if (newmsgs)
+						*newmsgs += tmpnew; 
+					if (oldmsgs)
+						*oldmsgs += tmpold;
+				}
+			}
+		}
+		return 0;
+	}
+	strncpy(tmp, mailbox, sizeof(tmp) - 1);
+	context = strchr(tmp, '@');
+	if (context) {
+		*context = '\0';
+		context++;
+	} else
+		context = "default";
+	if (newmsgs) {
+		snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, context, tmp);
+		dir = opendir(fn);
+		if (dir) {
+			while ((de = readdir(dir))) {
+				if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
+					!strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
+						(*newmsgs)++;
+					
+			}
+			closedir(dir);
+		}
+	}
+	if (oldmsgs) {
+		snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/Old", (char *)ast_config_AST_SPOOL_DIR, context, tmp);
+		dir = opendir(fn);
+		if (dir) {
+			while ((de = readdir(dir))) {
+				if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
+					!strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
+						(*oldmsgs)++;
+					
+			}
+			closedir(dir);
+		}
+	}
+	return 0;
+}
+
 static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
 
 static void copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt)
@@ -1885,7 +2005,7 @@ static void run_externnotify(char *context, char *extension)
 	int newvoicemails = 0, oldvoicemails = 0;
 
 	if (!ast_strlen_zero(externnotify)) {
-		if (ast_app_messagecount(extension, &newvoicemails, &oldvoicemails)) {
+		if (messagecount(extension, &newvoicemails, &oldvoicemails)) {
 			ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
 		} else {
 			snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
@@ -3037,7 +3157,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
 					ast_destroy(mif); /* or here */
 				}
 				/* Leave voicemail for someone */
-				manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, ast_app_has_voicemail(ext_context, NULL));
+				manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
 				run_externnotify(chan->context, ext_context);
 	
 				saved_messages++;
@@ -4755,7 +4875,7 @@ out:
 		close_mailbox(&vms, vmu);
 	if (valid) {
 		snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
-		manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, ast_app_has_voicemail(ext_context, NULL));
+		manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
 		run_externnotify(chan->context, ext_context);
 	}
 	if (vmu)
@@ -5415,6 +5535,7 @@ int unload_module(void)
 	res |= ast_unregister_application(app4);
 	ast_cli_unregister(&show_voicemail_users_cli);
 	ast_cli_unregister(&show_voicemail_zones_cli);
+	ast_uninstall_vm_functions();
 	return res;
 }
 
@@ -5431,8 +5552,12 @@ int load_module(void)
 	if ((res=load_config())) {
 		return(res);
 	}
+
 	ast_cli_register(&show_voicemail_users_cli);
 	ast_cli_register(&show_voicemail_zones_cli);
+
+	ast_install_vm_functions(has_voicemail, messagecount);
+
 	return res;
 }
 
@@ -5831,3 +5956,4 @@ char *key()
 {
 	return ASTERISK_GPL_KEY;
 }
+
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index 806b87c7d7f2c7ce2d66b04a06c1d8f6a666be6e..ba7d823c0b4c2ab541b12ab5be6db1e21f5373e5 100755
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -39,11 +39,16 @@ extern int ast_app_getdata_full(struct ast_channel *c, char *prompt, char *s, in
 //! Record voice (after playing prompt if specified), waiting for silence (in ms) up to a given timeout (in s) or '#'
 int ast_app_getvoice(struct ast_channel *c, char *dest, char *dstfmt, char *prompt, int silence, int maxsec);
 
+void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
+			      int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs));
+  
+void ast_uninstall_vm_functions(void);
+
 //! Determine if a given mailbox has any voicemail
-extern int ast_app_has_voicemail(const char *mailbox, const char *folder);
+int ast_app_has_voicemail(const char *mailbox, const char *folder);
 
 //! Determine number of new/old messages in a mailbox
-extern int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs);
+int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs);
 
 //! Safely spawn an external program while closingn file descriptors
 extern int ast_safe_system(const char *s);