Index: apps/app_voicemail.c
===================================================================
--- apps/app_voicemail.c	(revision 113647)
+++ apps/app_voicemail.c	(working copy)
@@ -221,6 +221,7 @@
 #define VM_SEARCH        (1 << 14)
 #define VM_TEMPGREETWARN (1 << 15)  /*!< Remind user tempgreeting is set */
 #define VM_MOVEHEARD     (1 << 16)  /*!< Move a "heard" message to Old after listening to it */
+#define VM_MESSAGEWRAP   (1 << 17)
 #define ERROR_LOCK_PATH  -100
 #define ERROR_MAILBOX_FULL	-200
 
@@ -740,6 +741,8 @@
 		ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
 	} else if (!strcasecmp(var, "tempgreetwarn")) {
 		ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);	
+	} else if (!strcasecmp(var, "messagewrap")){
+		ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP);	
 	} else if (!strcasecmp(var, "operator")) {
 		ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);	
 	} else if (!strcasecmp(var, "envelope")) {
@@ -6842,7 +6845,7 @@
 	}
 }
 
-static int vm_instructions_en(struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
+static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced)
 {
 	int res = 0;
 	/* Play instructions and wait for new command */
@@ -6870,13 +6873,14 @@
 					res = vm_play_folder_name(chan, vms->vmbox);
 				res = ast_play_and_wait(chan, "vm-opts-full");
                         }
-			if (vms->curmsg)
+			if ((vms->curmsg) || ((ast_test_flag(vmu, VM_MESSAGEWRAP) && (vms->lastmsg>0))))
 				res = ast_play_and_wait(chan, "vm-prev");
 			if (!res && !skipadvanced)
 				res = ast_play_and_wait(chan, "vm-advopts");
 			if (!res)
 				res = ast_play_and_wait(chan, "vm-repeat");
-			if (!res && (vms->curmsg != vms->lastmsg))
+			if (!res && ( (vms->curmsg != vms->lastmsg) || 
+				((ast_test_flag(vmu, VM_MESSAGEWRAP) && (vms->lastmsg>0))) ) )
 				res = ast_play_and_wait(chan, "vm-next");
 			if (!res) {
 				if (!vms->deleted[vms->curmsg])
@@ -6907,7 +6911,7 @@
 	return res;
 }
 
-static int vm_instructions_tw(struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
+static int vm_instructions_tw(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms,  int skipadvanced)
 {
 	int res = 0;
 	/* Play instructions and wait for new command */
@@ -6925,18 +6929,18 @@
 			res = ast_play_and_wait(chan, "vm-opts");
 		if (!res) {
 			vms->starting = 0;
-			return vm_instructions_en(chan, vms, skipadvanced);
+			return vm_instructions_en(chan, vmu, vms, skipadvanced);
 		}
 	}
 	return res;
 }
 
-static int vm_instructions(struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
+static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced)
 {
 	if (vms->starting && !strcasecmp(chan->language, "tw")) { /* CHINESE (Taiwan) syntax */
-		return vm_instructions_tw(chan, vms, skipadvanced);
+		return vm_instructions_tw(chan, vmu, vms, skipadvanced);
 	} else {					/* Default to ENGLISH */
-		return vm_instructions_en(chan, vms, skipadvanced);
+		return vm_instructions_en(chan, vmu, vms, skipadvanced);
 	}
 }
 
@@ -7903,6 +7907,11 @@
 				cmd = play_message(chan, vmu, &vms);
 			} else {
 				cmd = ast_play_and_wait(chan, "vm-nomore");
+				if ((ast_test_flag(vmu, VM_MESSAGEWRAP)) && (vms.lastmsg > 0)) {
+					cmd = ast_play_and_wait(chan, "vm-goingtolast");
+					vms.curmsg=vms.lastmsg;
+					cmd = play_message(chan, vmu, &vms);
+				}
 			}
 			break;
 		case '6': /* Go to the next message */
@@ -7911,6 +7920,11 @@
 				cmd = play_message(chan, vmu, &vms);
 			} else {
 				cmd = ast_play_and_wait(chan, "vm-nomore");
+				if ((ast_test_flag(vmu, VM_MESSAGEWRAP)) && (vms.lastmsg > 0)) {
+					cmd = ast_play_and_wait(chan, "vm-goingtofirst");
+					vms.curmsg=0;
+					cmd = play_message(chan, vmu, &vms);
+				}
 			}
 			break;
 		case '7': /* Delete teh current message */
@@ -7937,6 +7951,11 @@
 						cmd = play_message(chan, vmu, &vms);
 					} else {
 						cmd = ast_play_and_wait(chan, "vm-nomore");
+						if ((ast_test_flag(vmu, VM_MESSAGEWRAP)) && (vms.lastmsg > 0)) {
+							cmd = ast_play_and_wait(chan, "vm-goingtofirst");
+							vms.curmsg=0;
+							cmd = play_message(chan, vmu, &vms);
+						}
 					}
 				}
 			} else /* Delete not valid if we haven't selected a message */
@@ -8007,6 +8026,11 @@
 					cmd = play_message(chan, vmu, &vms);
 				} else {
 					cmd = ast_play_and_wait(chan, "vm-nomore");
+					if ((ast_test_flag(vmu, VM_MESSAGEWRAP)) && (vms.lastmsg > 0)) {
+						cmd = ast_play_and_wait(chan, "vm-goingtofirst");
+						vms.curmsg=0;
+						cmd = play_message(chan, vmu, &vms);
+					}
 				}
 			}
 			break;
@@ -8018,7 +8042,7 @@
 				if (!cmd)
 					cmd = ast_play_and_wait(chan, "vm-opts");
 				if (!cmd)
-					cmd = vm_instructions(chan, &vms, 1);
+					cmd = vm_instructions(chan, vmu, &vms, 1);
 			} else
 				cmd = 0;
 			break;
@@ -8028,7 +8052,7 @@
 				adsi_status(chan, &vms);
 			break;
 		default:	/* Nothing */
-			cmd = vm_instructions(chan, &vms, 0);
+			cmd = vm_instructions(chan, vmu, &vms, 0);
 			break;
 		}
 	}
@@ -9132,6 +9156,12 @@
 			ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n");
 		}
 		ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN);
+		if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){
+			if (option_debug)
+				ast_log(LOG_DEBUG,"VM next message wrap enabled globally\n");
+			val = "yes";
+		}
+		ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP);	
 
 		if (!(val = ast_variable_retrieve(cfg, "general", "operator"))) {
 			ast_debug(1, "VM Operator break disabled globally\n");
Index: configs/voicemail.conf.sample
===================================================================
--- configs/voicemail.conf.sample	(revision 113647)
+++ configs/voicemail.conf.sample	(working copy)
@@ -241,6 +241,11 @@
 ; hidefromdir=yes	; Hide this mailbox from the directory produced by app_directory
 			;     The default is "no".
 ; tempgreetwarn=yes	; Remind the user that their temporary greeting is set
+
+;messagewrap=yes	; Enable next/last message to wrap around to
+			; first (from last) and last (from first) message
+			; The default is "yes".
+
 ; vm-password=custom_sound
 			;     Customize which sound file is used instead of the default
 			;     prompt that says: "password"
