diff --git a/CHANGES b/CHANGES
index 30ba4d4c835eb9b3ba541397345b906e8f837ac7..b0eb2a5d4f3c1a7f99d9715deb7861291467a705 100644
--- a/CHANGES
+++ b/CHANGES
@@ -21,6 +21,12 @@ ConfBridge
  * Added menu action participant_count.  This will playback the number of current
    participants in a conference.
 
+Voicemail
+------------------
+ * Addition of the VM_INFO function - see Dialplan function changes
+ * The imapserver, imapport, and imapflags configuration options can now be
+   overriden on a user by user basis.
+
 SIP Changes
 -----------
  * Asterisk will no longer substitute CID number for CID name into display
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index f4414d68b9204fd988863094b0a48e269b6aa7bd..8be69e5a6f03b41c443a18c2bf20fba5ad57c791 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -466,7 +466,7 @@ static void vmstate_delete(struct vm_state *vms);
 static void set_update(MAILSTREAM * stream);
 static void init_vm_state(struct vm_state *vms);
 static int save_body(BODY *body, struct vm_state *vms, char *section, char *format, int is_intro);
-static void get_mailbox_delimiter(MAILSTREAM *stream);
+static void get_mailbox_delimiter(struct vm_state *vms, MAILSTREAM *stream);
 static void mm_parsequota (MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota);
 static void imap_mailbox_name(char *spec, size_t len, struct vm_state *vms, int box, int target);
 static int imap_store_file(const char *dir, const char *mailboxuser, const char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms, const char *flag);
@@ -726,6 +726,9 @@ struct ast_vm_user {
 	int maxsecs;                     /*!< Maximum number of seconds per message for this mailbox */
 	int passwordlocation;            /*!< Storage location of the password */
 #ifdef IMAP_STORAGE
+	char imapserver[48];             /*!< IMAP server address */
+	char imapport[8];                /*!< IMAP server port */
+	char imapflags[128];             /*!< IMAP optional flags */
 	char imapuser[80];               /*!< IMAP server login */
 	char imappassword[80];           /*!< IMAP server password if authpassword not defined */
 	char imapfolder[64];             /*!< IMAP voicemail folder */
@@ -773,6 +776,9 @@ struct vm_state {
 	int vmArrayIndex;
 	char imapuser[80];                   /*!< IMAP server login */
 	char imapfolder[64];                 /*!< IMAP voicemail folder */
+	char imapserver[48];                 /*!< IMAP server address */
+	char imapport[8];                    /*!< IMAP server port */
+	char imapflags[128];                 /*!< IMAP optional flags */
 	int imapversion;
 	int interactive;
 	char introfn[PATH_MAX];              /*!< Name of prepended file */
@@ -1110,6 +1116,9 @@ static void populate_defaults(struct ast_vm_user *vmu)
 	vmu->emailbody = NULL;
 #ifdef IMAP_STORAGE
 	ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder));
+	ast_copy_string(vmu->imapserver, imapserver, sizeof(vmu->imapserver));
+	ast_copy_string(vmu->imapport, imapport, sizeof(vmu->imapport));
+	ast_copy_string(vmu->imapflags, imapflags, sizeof(vmu->imapflags));
 #endif
 }
 
@@ -1146,11 +1155,21 @@ static void apply_option(struct ast_vm_user *vmu, const char *var, const char *v
 	} else if (!strcasecmp(var, "imapuser")) {
 		ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
 		vmu->imapversion = imapversion;
+	} else if (!strcasecmp(var, "imapserver")) {
+		ast_copy_string(vmu->imapserver, value, sizeof(vmu->imapserver));
+		vmu->imapversion = imapversion;
+	} else if (!strcasecmp(var, "imapport")) {
+		ast_copy_string(vmu->imapport, value, sizeof(vmu->imapport));
+		vmu->imapversion = imapversion;
+	} else if (!strcasecmp(var, "imapflags")) {
+		ast_copy_string(vmu->imapflags, value, sizeof(vmu->imapflags));
+		vmu->imapversion = imapversion;
 	} else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) {
 		ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
 		vmu->imapversion = imapversion;
 	} else if (!strcasecmp(var, "imapfolder")) {
 		ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder));
+		vmu->imapversion = imapversion;
 	} else if (!strcasecmp(var, "imapvmshareid")) {
 		ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid));
 		vmu->imapversion = imapversion;
@@ -1417,11 +1436,21 @@ static void apply_options_full(struct ast_vm_user *retval, struct ast_variable *
 		} else if (!strcasecmp(var->name, "imapuser")) {
 			ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser));
 			retval->imapversion = imapversion;
+		} else if (!strcasecmp(var->name, "imapserver")) {
+			ast_copy_string(retval->imapserver, var->value, sizeof(retval->imapserver));
+			retval->imapversion = imapversion;
+		} else if (!strcasecmp(var->name, "imapport")) {
+			ast_copy_string(retval->imapport, var->value, sizeof(retval->imapport));
+			retval->imapversion = imapversion;
+		} else if (!strcasecmp(var->name, "imapflags")) {
+			ast_copy_string(retval->imapflags, var->value, sizeof(retval->imapflags));
+			retval->imapversion = imapversion;
 		} else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) {
 			ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword));
 			retval->imapversion = imapversion;
 		} else if (!strcasecmp(var->name, "imapfolder")) {
 			ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder));
+			retval->imapversion = imapversion;
 		} else if (!strcasecmp(var->name, "imapvmshareid")) {
 			ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid));
 			retval->imapversion = imapversion;
@@ -2584,15 +2613,16 @@ static void imap_mailbox_name(char *spec, size_t len, struct vm_state *vms, int
 	}
 
 	/* Build up server information */
-	ast_build_string(&t, &left, "{%s:%s/imap", imapserver, imapport);
+	ast_build_string(&t, &left, "{%s:%s/imap", S_OR(vms->imapserver, imapserver), S_OR(vms->imapport, imapport));
 
 	/* Add authentication user if present */
 	if (!ast_strlen_zero(authuser))
 		ast_build_string(&t, &left, "/authuser=%s", authuser);
 
 	/* Add flags if present */
-	if (!ast_strlen_zero(imapflags))
-		ast_build_string(&t, &left, "/%s", imapflags);
+	if (!ast_strlen_zero(imapflags) || !(ast_strlen_zero(vms->imapflags))) {
+		ast_build_string(&t, &left, "/%s", S_OR(vms->imapflags, imapflags));
+	}
 
 	/* End with username */
 #if 1
@@ -2651,7 +2681,7 @@ static int init_mailstream(struct vm_state *vms, int box)
 			ast_log(LOG_ERROR, "Can't connect to imap server %s\n", tmp);
 			return -1;
 		}
-		get_mailbox_delimiter(stream);
+		get_mailbox_delimiter(vms, stream);
 		/* update delimiter in imapfolder */
 		for (cp = vms->imapfolder; *cp; cp++)
 			if (*cp == '/')
@@ -2684,6 +2714,9 @@ static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box)
 
 	ast_copy_string(vms->imapuser, vmu->imapuser, sizeof(vms->imapuser));
 	ast_copy_string(vms->imapfolder, vmu->imapfolder, sizeof(vms->imapfolder));
+	ast_copy_string(vms->imapserver, vmu->imapserver, sizeof(vms->imapserver));
+	ast_copy_string(vms->imapport, vmu->imapport, sizeof(vms->imapport));
+	ast_copy_string(vms->imapflags, vmu->imapflags, sizeof(vms->imapflags));
 	vms->imapversion = vmu->imapversion;
 	ast_debug(3, "Before init_mailstream, user is %s\n", vmu->imapuser);
 
@@ -3049,6 +3082,9 @@ static struct vm_state *create_vm_state_from_user(struct ast_vm_user *vmu)
 		return NULL;
 	ast_copy_string(vms_p->imapuser, vmu->imapuser, sizeof(vms_p->imapuser));
 	ast_copy_string(vms_p->imapfolder, vmu->imapfolder, sizeof(vms_p->imapfolder));
+	ast_copy_string(vms_p->imapserver, vmu->imapserver, sizeof(vms_p->imapserver));
+	ast_copy_string(vms_p->imapport, vmu->imapport, sizeof(vms_p->imapport));
+	ast_copy_string(vms_p->imapflags, vmu->imapflags, sizeof(vms_p->imapflags));
 	ast_copy_string(vms_p->username, vmu->mailbox, sizeof(vms_p->username)); /* save for access from interactive entry point */
 	ast_copy_string(vms_p->context, vmu->context, sizeof(vms_p->context));
 	vms_p->mailstream = NIL; /* save for access from interactive entry point */
@@ -3280,14 +3316,15 @@ static int save_body(BODY *body, struct vm_state *vms, char *section, char *form
 
 /*! 
  * \brief Get delimiter via mm_list callback 
+ * \param vms		The voicemail state object
  * \param stream
  *
  * Determines the delimiter character that is used by the underlying IMAP based mail store.
  */
 /* MUTEX should already be held */
-static void get_mailbox_delimiter(MAILSTREAM *stream) {
+static void get_mailbox_delimiter(struct vm_state *vms, MAILSTREAM *stream) {
 	char tmp[50];
-	snprintf(tmp, sizeof(tmp), "{%s}", imapserver);
+	snprintf(tmp, sizeof(tmp), "{%s}", S_OR(vms->imapserver, imapserver));
 	mail_list(stream, tmp, "*");
 }
 
@@ -10877,7 +10914,7 @@ AST_TEST_DEFINE(test_voicemail_vmuser)
 		"[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}";
 #ifdef IMAP_STORAGE
 	static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|"
-		"imapfolder=INBOX|imapvmshareid=6000";
+		"imapfolder=INBOX|imapvmshareid=6000|imapserver=imapserver|imapport=1234|imapflags=flagged";
 #endif
 
 	switch (cmd) {
@@ -11031,6 +11068,18 @@ AST_TEST_DEFINE(test_voicemail_vmuser)
 		ast_test_status_update(test, "Parse failure for imapvmshareid option\n");
 		res = 1;
 	}
+	if (strcasecmp(vmu->imapserver, "imapserver")) {
+		ast_test_status_update(test, "Parse failure for imapserver option\n");
+		res = 1;
+	}
+	if (strcasecmp(vmu->imapport, "1234")) {
+		ast_test_status_update(test, "Parse failure for imapport option\n");
+		res = 1;
+	}
+	if (strcasecmp(vmu->imapflags, "flagged")) {
+		ast_test_status_update(test, "Parse failure for imapflags option\n");
+		res = 1;
+	}
 #endif
 
 	free_user(vmu);
@@ -11823,6 +11872,9 @@ static int manager_list_voicemail_users(struct mansession *s, const struct messa
 #ifdef IMAP_STORAGE
 			"OldMessageCount: %d\r\n"
 			"IMAPUser: %s\r\n"
+			"IMAPServer: %s\r\n"
+			"IMAPPort: %s\r\n"
+			"IMAPFlags: %s\r\n"
 #endif
 			"\r\n",
 			actionid,
@@ -11851,7 +11903,11 @@ static int manager_list_voicemail_users(struct mansession *s, const struct messa
 			vmu->maxmsg,
 			vmu->maxsecs,
 #ifdef IMAP_STORAGE
-			new, old, vmu->imapuser
+			new, old,
+			vmu->imapuser,
+			vmu->imapserver,
+			vmu->imapport,
+			vmu->imapflags
 #else
 			count_messages(vmu, dirname)
 #endif
diff --git a/configs/voicemail.conf.sample b/configs/voicemail.conf.sample
index c2cbdf2e39891326995673c9eeb3043dbb4394d7..a92e7a1c5b88f78617bb980e01df1d566a4d861e 100644
--- a/configs/voicemail.conf.sample
+++ b/configs/voicemail.conf.sample
@@ -185,20 +185,43 @@ pagerdateformat=%A, %B %d, %Y at %r
 ;pollfreq=30         ;   If the "pollmailboxes" option is enabled, this option
 ;                    ; sets the polling frequency.  The default is once every
 ;                    ; 30 seconds.
-; If using IMAP storage, specify whether voicemail greetings should be stored
-; via IMAP. If no, then greetings are stored as if IMAP storage were not enabled
-;imapgreetings=no
-; If imapgreetings=yes, then specify which folder to store your greetings in. If
-; you do not specify a folder, then INBOX will be used
-;greetingsfolder=INBOX
-; Some IMAP server implementations store folders under INBOX instead of
-; using a top level folder (ex. INBOX/Friends).  In this case, user
-; imapparentfolder to set the parent folder. For example, Cyrus IMAP does
-; NOT use INBOX as the parent. Default is to have no parent folder set.
-;imapparentfolder=INBOX
-;
 ;
+
+; -----------------------------------------------------------------------------
+; IMAP configuration settings only
+;   These settings are only applicable when Asterisk is compiled with IMAP support.
+;
+;imapgreetings=no        ; If using IMAP storage, specify whether voicemail greetings
+                         ; should be stored via IMAP. If no, then greetings are stored
+                         ; as if IMAP storage were not enabled.
+;greetingsfolder=INBOX   ; If imapgreetings=yes, then specify which folder to store
+                         ; your greetings in. If you do not specify a folder, then INBOX
+                         ; will be used
+;imapparentfolder=INBOX  ; Some IMAP server implementations store folders under INBOX
+                         ; instead of using a top level folder (ex. INBOX/Friends).  In
+                         ; this case, user imapparentfolder to set the parent folder. For
+                         ; example, Cyrus IMAP does NOT use INBOX as the parent. Default
+                         ; is to have no parent folder set.
+;imapserver=localhost    ; The address of the IMAP server
+;imapport=143            ; The port of the IMAP server
+;imapflags=ssl           ; Optional flags to pass to the IMAP server in the IMAP mailbox
+                         ; name.  For example, setting this to 'ssl' will enable OpenSSL
+                         ; encryption, assuming the IMAP libraries were compiled with
+                         ; OpenSSL support.
+;imapfolder=INBOX        ; The folder in which to store voicemail messages on the IMAP
+                         ; server.  By default, they are stored in INBOX.
+;authuser=user           ; The master user to use for connecting to the IMAP server, if
+                         ; the server is configured with a single user that has access to
+                         ; all mailboxes
+;authpassword=password   ; The password for the authuser, if used
+;imapopentimeout=60      ; The TCP open timeout (in seconds)
+;imapclosetimeout=60     ; The TCP close timeout (in seconds)
+;imapreadtimeout=60      ; The TCP read timeout (in seconds)
+;imapwritetimeout=60     ; The TCP write timeout (in seconds)
+
+; -----------------------------------------------------------------------------
 ;
+
 ; Each mailbox is listed in the form <mailbox>=<password>,<name>,<email>,<pager_email>,<options>
 ; if the e-mail is specified, a message will be sent when a message is
 ; received, to the given mailbox. If pager is specified, a message will be
@@ -413,9 +436,19 @@ european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM
 ;112 => 6262,Nancy,nancy@acme-widgets.com
 ;
 
-;
-; When using IMAP storage, imapuser, imappassword, and imapfolder can be used to specify the
-; user's credentials.
+; ---------------------------------------------------------------------------
+; IMAP user settings and overrides.  These are only applicable when Asterisk is
+; compiled with IMAP support.
+;
+; imapuser=username                ; The IMAP username of the mailbox to access
+; imappassword=password            ; The IMAP password of the user
+; imapvmshareid=xxxx               ; A shared mailbox ID to use for the IMAP mailbox
+                                   ; login, as opposed to the mailbox dialed
+; imapfolder                       ; Overrides the global imapfolder setting
+; imapserver                       ; Overrides the global imapserver setting
+; imapport                         ; Overrides the global imapport setting
+; imapflags                        ; Overrides the global imapflags setting
+
 ;
 ;[imapvm]
 ;4324 => 7764,Ellis Redding,red@buxton.us,,imapuser=eredding|imappassword=g3tbusy|imapfolder=notinbox
diff --git a/contrib/realtime/mysql/voicemail.sql b/contrib/realtime/mysql/voicemail.sql
index c8148cfcbf0d125290421cd09aa162f4c7428cda..bd924f4265f9680fd96077f7e72c164a80651e25 100644
--- a/contrib/realtime/mysql/voicemail.sql
+++ b/contrib/realtime/mysql/voicemail.sql
@@ -60,5 +60,11 @@ CREATE TABLE voicemail (
 	imapuser VARCHAR(80),
 	-- IMAP password for authentication (if using IMAP storage)
 	imappassword VARCHAR(80),
+	-- IMAP server location (if using IMAP storage)
+	imapsever VARCHAR(80),
+	-- IMAP port (if using IMAP storage)
+	imapport VARCHAR(8),
+	-- IMAP flags (if using IMAP storage)
+	imapflags VARCHAR(80),
 	stamp timestamp
 );