diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index a7b43a88d7ec4c16979bef79b7c9b3bbd57f0509..ced94c639363fa01094a3fd9b43ddc7d2edb8a96 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -109,6 +109,23 @@ struct vm_zone {
 	struct vm_zone *next;
 };
 
+struct vm_state {
+	char curbox[80];
+	char username[80];
+	char curdir[256];
+	char vmbox[256];
+	char fn[256];
+	char fn2[256];
+	int deleted[MAXMSG];
+	int heard[MAXMSG];
+	int curmsg;
+	int lastmsg;
+	int newmessages;
+	int oldmessages;
+	int starting;
+	int repeats;
+};
+
 static char *tdesc = "Comedian Mail (Voicemail System)";
 
 static char *adapp = "CoMa";
@@ -874,6 +891,214 @@ static int play_and_wait(struct ast_channel *chan, char *fn)
 	return d;
 }
 
+static int play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt)
+{
+	char d, *fmts;
+	char comment[256];
+	int x, fmtcnt=1, res=-1,outmsg=0;
+	struct ast_frame *f;
+	struct ast_filestream *others[MAX_OTHER_FORMATS];
+	struct ast_filestream *realfiles[MAX_OTHER_FORMATS];
+	char *sfmt[MAX_OTHER_FORMATS];
+	char *stringp=NULL;
+	time_t start, end;
+	struct ast_dsp *sildet;   	/* silence detector dsp */
+	int totalsilence = 0;
+	int dspsilence = 0;
+	int gotsilence = 0;		/* did we timeout for silence? */
+	int rfmt=0;	
+	char prependfile[80];
+	
+	ast_log(LOG_DEBUG,"play_and_preped: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
+	snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name);
+
+	if (playfile) {	
+		d = play_and_wait(chan, playfile);
+		if (d > -1)
+			d = ast_streamfile(chan, "beep",chan->language);
+		if (!d)
+			d = ast_waitstream(chan,"");
+		if (d < 0)
+			return -1;
+	}
+	strncpy(prependfile, recordfile, sizeof(prependfile) -1);	
+	strcat(prependfile, "-prepend");
+			
+	fmts = ast_strdupa(fmt);
+	
+	stringp=fmts;
+	strsep(&stringp, "|");
+	ast_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts);	
+	sfmt[0] = ast_strdupa(fmts);
+	
+	while((fmt = strsep(&stringp, "|"))) {
+		if (fmtcnt > MAX_OTHER_FORMATS - 1) {
+			ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app_voicemail.c\n");
+			break;
+		}
+		sfmt[fmtcnt++] = ast_strdupa(fmt);
+	}
+
+	if (maxtime)
+		time(&start);
+	for (x=0;x<fmtcnt;x++) {
+		others[x] = ast_writefile(prependfile, sfmt[x], comment, O_TRUNC, 0, 0700);
+		ast_verbose( VERBOSE_PREFIX_3 "x=%i, open writing:  %s format: %s, %p\n", x, prependfile, sfmt[x], others[x]);
+		if (!others[x]) {
+			break;
+		}
+	}
+	
+	sildet = ast_dsp_new(); //Create the silence detector
+	if (!sildet) {
+		ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
+		return -1;
+	}
+	ast_dsp_set_threshold(sildet, silencethreshold);
+	
+	if (maxsilence > 0) {
+		rfmt = chan->readformat;
+		res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+		if (res < 0) {
+			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
+			return -1;
+		}
+	}
+						
+	if (x == fmtcnt) {
+	/* Loop forever, writing the packets we read to the writer(s), until
+	   we read a # or get a hangup */
+		f = NULL;
+		for(;;) {
+		 	res = ast_waitfor(chan, 2000);
+			if (!res) {
+				ast_log(LOG_DEBUG, "One waitfor failed, trying another\n");
+				/* Try one more time in case of masq */
+			 	res = ast_waitfor(chan, 2000);
+				if (!res) {
+					ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
+					res = -1;
+				}
+			}
+			
+			if (res < 0) {
+				f = NULL;
+				break;
+			}
+			f = ast_read(chan);
+			if (!f)
+				break;
+			if (f->frametype == AST_FRAME_VOICE) {
+				/* write each format */
+				for (x=0;x<fmtcnt;x++) {
+					if (!others[x])
+						break;
+					res = ast_writestream(others[x], f);
+				}
+				
+				/* Silence Detection */
+				if (maxsilence > 0) {
+					dspsilence = 0;
+					ast_dsp_silence(sildet, f, &dspsilence);
+					if (dspsilence)
+						totalsilence = dspsilence;
+					else
+						totalsilence = 0;
+					
+					if (totalsilence > maxsilence) {
+					/* Ended happily with silence */
+					ast_frfree(f);
+					gotsilence = 1;
+					outmsg=2;
+					break;
+					}
+				}
+				/* Exit on any error */
+				if (res) {
+					ast_log(LOG_WARNING, "Error writing frame\n");
+					ast_frfree(f);
+					break;
+				}
+			} else if (f->frametype == AST_FRAME_VIDEO) {
+				/* Write only once */
+				ast_writestream(others[0], f);
+			} else if (f->frametype == AST_FRAME_DTMF) {
+				/* stop recording with any digit */
+				if (option_verbose > 2) 
+					ast_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
+				res = f->subclass;
+				outmsg = 2;
+				ast_frfree(f);
+				break;
+			}
+			if (maxtime) {
+				time(&end);
+				if (maxtime < (end - start)) {
+					if (option_verbose > 2)
+						ast_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
+					res = 't';
+					ast_frfree(f);
+					break;
+				}
+			}
+			ast_frfree(f);
+		}
+		if (!f) {
+			if (option_verbose > 2) 
+				ast_verbose( VERBOSE_PREFIX_3 "User hung up\n");
+			res = -1;
+			outmsg=1;
+			/* delete all the prepend files */
+			for (x=0;x<fmtcnt;x++) {
+				if (!others[x])
+					break;
+				ast_closestream(others[x]);
+				ast_filedelete(prependfile, sfmt[x]);
+			}
+		}
+	} else {
+		ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", prependfile, sfmt[x]); 
+	}
+	if (outmsg > 1) {
+		struct ast_frame *fr;
+		for (x=0;x<fmtcnt;x++) {
+			snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]);
+			realfiles[x] = ast_writefile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0);
+			if (!others[x] || !realfiles[x])
+				break;
+			if (totalsilence)
+				ast_stream_rewind(others[x], totalsilence-200);
+			else
+				ast_stream_rewind(others[x], 200);
+			ast_truncstream(others[x]);
+			/* add the original file too */
+			while ((fr = ast_readframe(realfiles[x]))) {
+				ast_writestream(others[x],fr);
+			}
+			ast_closestream(others[x]);
+			ast_closestream(realfiles[x]);
+			ast_filerename(prependfile, recordfile, sfmt[x]);
+#if 0
+			ast_verbose("Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x],prependfile,recordfile);
+#endif
+			ast_filedelete(prependfile, sfmt[x]);
+		}
+	}
+	if (rfmt) {
+		if (ast_set_read_format(chan, rfmt)) {
+			ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
+		}
+	}
+	if (outmsg) {
+		if (outmsg > 1) {
+			/* Let them know it worked */
+			ast_streamfile(chan, "vm-msgsaved", chan->language);
+			ast_waitstream(chan, "");
+		}
+	}	
+	return res;
+}
+
 static int play_and_record(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt)
 {
 	char d, *fmts;
@@ -1891,8 +2116,45 @@ static int get_folder2(struct ast_channel *chan, char *fn, int start)
 	return res;
 }
 
-static int
-forward_message(struct ast_channel *chan, char *context, char *dir, int curmsg, struct ast_vm_user *sender, char *fmt)
+static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfts, char *context)
+{
+	int cmd = 0;
+	int retries = 0;
+
+	while((cmd >= 0) && (cmd != 't') && (cmd != '#')) {
+		if (cmd)
+			retries = 0;
+		switch (cmd) {
+		case '1': 
+			/* prepend a message to the current message and return */
+		{
+			char file[200];
+			snprintf(file, sizeof(file), "%s/msg%04d", curdir, curmsg);
+			cmd = play_and_prepend(chan, NULL, file, 0, vmfmts);
+			break;
+		}
+		case '2': 
+			cmd = 't';
+			break;
+		case '#':
+			cmd = '#';
+			break;
+		default: 
+			cmd = play_and_wait(chan,"vm-forwardoptions");
+			if (!cmd)
+				cmd = ast_waitfordigit(chan,6000);
+			if (!cmd)
+				retries++;
+			if (retries > 3)
+				cmd = 't';
+		 }
+	}
+	if (cmd == 't')
+		cmd = 0;
+	return cmd;
+}
+
+static int forward_message(struct ast_channel *chan, char *context, char *dir, int curmsg, struct ast_vm_user *sender, char *fmt)
 {
 	char username[70];
 	char sys[256];
@@ -1903,106 +2165,127 @@ forward_message(struct ast_channel *chan, char *context, char *dir, int curmsg,
 	char miffile[256];
 	char fn[256];
 	char callerid[512];
-	int res = 0;
-	struct ast_vm_user *receiver, srec;
+	int res = 0, cmd = 0;
+	struct ast_vm_user *receiver, *extensions = NULL, *vmtmp = NULL;
 	char tmp[256];
 	char *stringp, *s;
-	
-	while(!res) {
+	int saved_messages = 0, found = 0;
+	int valid_extensions = 0;
+	while (!res && !valid_extensions) {
 		res = ast_streamfile(chan, "vm-extension", chan->language);
 		if (res)
 			break;
 		if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
 			break;
-		if ((receiver = find_user(&srec, context, username))) {
-			/* if (play_and_wait(chan, "vm-savedto"))
+		/* start all over if no username */
+		if (!strlen(username))
+			continue;
+		stringp = username;
+		s = strsep(&stringp, "*");
+		/* start optimistic */
+		valid_extensions = 1;
+		while (s) {
+			/* find_user is going to malloc since we have a NULL as first argument */
+			if ((receiver = find_user(NULL, context, s))) {
+				if (!extensions)
+					vmtmp = extensions = receiver;
+				else {
+					vmtmp->next = receiver;
+					vmtmp = receiver;
+				}
+				found++;
+			} else {
+				valid_extensions = 0;
 				break;
-			*/
+			}
+			s = strsep(&stringp, "*");
+		}
+		/* break from the loop of reading the extensions */
+		if (valid_extensions)
+			break;
+		/* invalid extension, try again */
+		res = play_and_wait(chan, "pbx-invalid");
+	}
+	/* check if we're clear to proceed */
+	if (!extensions || !valid_extensions)
+		return res;
+	vmtmp = extensions;
+	cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context);
 
-			snprintf(todir, sizeof(todir), "%s/voicemail/%s/%s/INBOX",  (char *)ast_config_AST_SPOOL_DIR, receiver->context, username);
-			snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir);
+	while(!res && vmtmp) {
+		/* if (play_and_wait(chan, "vm-savedto"))
+			break;
+		*/
+		snprintf(todir, sizeof(todir), "%s/voicemail/%s/%s/INBOX",  (char *)ast_config_AST_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
+		snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir);
+		ast_log(LOG_DEBUG, sys);
+		system(sys);
+
+		todircount = count_messages(todir);
+		strncpy(tmp, fmt, sizeof(tmp));
+		stringp = tmp;
+		while((s = strsep(&stringp, "|"))) {
+			/* XXX This is a hack -- we should use build_filename or similar XXX */
+			if (!strcasecmp(s, "wav49"))
+				s = "WAV";
+			snprintf(sys, sizeof(sys), "cp %s/msg%04d.%s %s/msg%04d.%s\n", dir, curmsg, s, todir, todircount, s);
 			ast_log(LOG_DEBUG, sys);
 			system(sys);
+		}
+		snprintf(sys, sizeof(sys), "cp %s/msg%04d.txt %s/msg%04d.txt\n", dir, curmsg, todir, todircount);
+		ast_log(LOG_DEBUG, sys);
+		system(sys);
+		snprintf(fn, sizeof(fn), "%s/msg%04d", todir,todircount);
 
-			todircount = count_messages(todir);
-			strncpy(tmp, fmt, sizeof(tmp));
-			stringp = tmp;
-			while((s = strsep(&stringp, "|"))) {
-				/* XXX This is a hack -- we should use build_filename or similar XXX */
-				if (!strcasecmp(s, "wav49"))
-					s = "WAV";
-				snprintf(sys, sizeof(sys), "cp %s/msg%04d.%s %s/msg%04d.%s\n", dir, curmsg, s, todir, todircount, s);
-				ast_log(LOG_DEBUG, sys);
-				system(sys);
-			}
-			snprintf(sys, sizeof(sys), "cp %s/msg%04d.txt %s/msg%04d.txt\n", dir, curmsg, todir, todircount);
-			ast_log(LOG_DEBUG, sys);
-			system(sys);
-			snprintf(fn, sizeof(fn), "%s/msg%04d", todir,todircount);
-
-			/* load the information on the source message so we can send an e-mail like a new message */
-			snprintf(miffile, sizeof(miffile), "%s/msg%04d.txt", dir, curmsg);
-			if ((mif=ast_load(miffile))) {
-
-              /* set callerid and duration variables */
-              snprintf(callerid, sizeof(callerid), "FWD from: %s from %s", sender->fullname, ast_variable_retrieve(mif, NULL, "callerid"));
-	      s = ast_variable_retrieve(mif, NULL, "duration");
-              if (s)
-		      duration = atol(s);
-	      else
-		      duration = 0;
-	      if (strlen(receiver->email)) {
+		/* load the information on the source message so we can send an e-mail like a new message */
+		snprintf(miffile, sizeof(miffile), "%s/msg%04d.txt", dir, curmsg);
+		if ((mif=ast_load(miffile))) {
+
+			/* set callerid and duration variables */
+			snprintf(callerid, sizeof(callerid), "FWD from: %s from %s", sender->fullname, ast_variable_retrieve(mif, NULL, "callerid"));
+			s = ast_variable_retrieve(mif, NULL, "duration");
+			if (s)
+				duration = atol(s);
+			else
+				duration = 0;
+			if (strlen(vmtmp->email)) {
 				int attach_user_voicemail = attach_voicemail;
 				char *myserveremail = serveremail;
-				if (receiver->attach > -1)
-					attach_user_voicemail = receiver->attach;
-				if (strlen(receiver->serveremail))
-					myserveremail = receiver->serveremail;
-		      sendmail(myserveremail, receiver, todircount, username, callerid, fn, tmp, duration, attach_user_voicemail);
-	      }
-	     
-			if (strlen(receiver->pager)) {
+				if (vmtmp->attach > -1)
+					attach_user_voicemail = vmtmp->attach;
+				if (strlen(vmtmp->serveremail))
+					myserveremail = vmtmp->serveremail;
+				sendmail(myserveremail, vmtmp, todircount, vmtmp->mailbox, callerid, fn, tmp, duration, attach_user_voicemail);
+			}
+		     
+			if (strlen(vmtmp->pager)) {
 				char *myserveremail = serveremail;
-				if (strlen(receiver->serveremail))
-					myserveremail = receiver->serveremail;
-				sendpage(myserveremail, receiver->pager, todircount, username, callerid, duration, receiver);
+				if (strlen(vmtmp->serveremail))
+					myserveremail = vmtmp->serveremail;
+				sendpage(myserveremail, vmtmp->pager, todircount, vmtmp->mailbox, callerid, duration, vmtmp);
 			}
 			  
-			  ast_destroy(mif); /* or here */
-			}
-			/* Leave voicemail for someone */
-			manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", username, ast_app_has_voicemail(username));
+			ast_destroy(mif); /* or here */
+		}
+		/* Leave voicemail for someone */
+		manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", vmtmp->mailbox, ast_app_has_voicemail(vmtmp->mailbox));
 
-			/* give confirmatopm that the message was saved */
+		free_user(vmtmp);
+		saved_messages++;
+		vmtmp = vmtmp->next;
+	}
+	if (saved_messages > 0) {
+		/* give confirmatopm that the message was saved */
+		if (saved_messages == 1)
 			res = play_and_wait(chan, "vm-message");
-			if (!res)
-				res = play_and_wait(chan, "vm-saved");
-			free_user(receiver);
-			break;
-		} else {
-			res = play_and_wait(chan, "pbx-invalid");
-		}
+		else
+			res = play_and_wait(chan, "vm-messages");
+		if (!res)
+			res = play_and_wait(chan, "vm-saved");
 	}
-	return res;
+	return res ? res : cmd;
 }
 
-struct vm_state {
-	char curbox[80];
-	char username[80];
-	char curdir[256];
-	char vmbox[256];
-	char fn[256];
-	char fn2[256];
-	int deleted[MAXMSG];
-	int heard[MAXMSG];
-	int curmsg;
-	int lastmsg;
-	int newmessages;
-	int oldmessages;
-	int starting;
-	int repeats;
-};
-
 
 static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file)
 {
diff --git a/file.c b/file.c
index 4213a23e2dc1c98e70f0d513199f52e02673be3d..9869eb325f8e6f7c389a4fb027556b8292314d1c 100755
--- a/file.c
+++ b/file.c
@@ -499,6 +499,15 @@ struct ast_filestream *ast_openvstream(struct ast_channel *chan, char *filename,
 	return NULL;
 }
 
+struct ast_frame *ast_readframe(struct ast_filestream *s)
+{
+	struct ast_frame *f = NULL;
+	int whennext = 0;	
+	if (s && s->fmt)
+		f = s->fmt->read(s, &whennext);
+	return f;
+}
+
 static int ast_readaudio_callback(void *data)
 {
 	struct ast_filestream *s = data;
@@ -726,10 +735,58 @@ int ast_streamfile(struct ast_channel *chan, char *filename, char *preflang)
 	return -1;
 }
 
+struct ast_filestream *ast_readfile(char *filename, char *type, char *comment, int flags, int check, mode_t mode)
+{
+	int fd,myflags = 0;
+	struct ast_format *f;
+	struct ast_filestream *fs=NULL;
+	char *fn;
+	char *ext;
+	if (ast_mutex_lock(&formatlock)) {
+		ast_log(LOG_WARNING, "Unable to lock format list\n");
+		return NULL;
+	}
+	f = formats;
+	while(f) {
+		if (!strcasecmp(f->name, type)) {
+			char *stringp=NULL;
+			/* XXX Implement check XXX */
+			ext = strdup(f->exts);
+			stringp=ext;
+			ext = strsep(&stringp, "|");
+			fn = build_filename(filename, ext);
+			fd = open(fn, flags | myflags);
+			if (fd >= 0) {
+				errno = 0;
+				if ((fs = f->open(fd))) {
+					fs->trans = NULL;
+					fs->fmt = f;
+					fs->flags = flags;
+					fs->mode = mode;
+					fs->filename = strdup(filename);
+					fs->vfs = NULL;
+				} else {
+					ast_log(LOG_WARNING, "Unable to open %s\n", fn);
+					close(fd);
+					unlink(fn);
+				}
+			} else if (errno != EEXIST)
+				ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
+			free(fn);
+			free(ext);
+			break;
+		}
+		f = f->next;
+	}
+	ast_mutex_unlock(&formatlock);
+	if (!f) 
+		ast_log(LOG_WARNING, "No such format '%s'\n", type);
+	return fs;
+}
 
 struct ast_filestream *ast_writefile(char *filename, char *type, char *comment, int flags, int check, mode_t mode)
 {
-	int fd,myflags;
+	int fd,myflags = 0;
 	struct ast_format *f;
 	struct ast_filestream *fs=NULL;
 	char *fn;
@@ -738,9 +795,12 @@ struct ast_filestream *ast_writefile(char *filename, char *type, char *comment,
 		ast_log(LOG_WARNING, "Unable to lock format list\n");
 		return NULL;
 	}
-	myflags = 0;
 	/* set the O_TRUNC flag if and only if there is no O_APPEND specified */
-	if (!(flags & O_APPEND)) myflags = O_TRUNC;
+	if (!(flags & O_APPEND)) 
+		myflags = O_TRUNC;
+	
+	myflags |= O_WRONLY | O_CREAT;
+
 	f = formats;
 	while(f) {
 		if (!strcasecmp(f->name, type)) {
@@ -750,7 +810,7 @@ struct ast_filestream *ast_writefile(char *filename, char *type, char *comment,
 			stringp=ext;
 			ext = strsep(&stringp, "|");
 			fn = build_filename(filename, ext);
-			fd = open(fn, flags | myflags | O_WRONLY | O_CREAT, mode);
+			fd = open(fn, flags | myflags, mode);
 			if (fd >= 0) {
 				errno = 0;
 				if ((fs = f->rewrite(fd, comment))) {
diff --git a/include/asterisk/file.h b/include/asterisk/file.h
index f7808e435c2b9fc5fe2f8ad848e111f22e95a8dd..316e4711219a89ee4258061ffc1efdd9bc37f438 100755
--- a/include/asterisk/file.h
+++ b/include/asterisk/file.h
@@ -140,6 +140,22 @@ char ast_waitstream_fr(struct ast_channel *c, char *breakon, char *forward, char
    1 if monfd is ready for reading */
 char ast_waitstream_full(struct ast_channel *c, char *breakon, int audiofd, int monfd);
 
+//! Starts reading from a file
+/*!
+ * \param filename the name of the file to write to
+ * \param type format of file you wish to write out to
+ * \param comment comment to go with
+ * \param oflags output file flags
+ * \param check (unimplemented, hence negligible)
+ * \param mode Open mode
+ * Open an incoming file stream.  oflags are flags for the open() command, and 
+ * if check is non-zero, then it will not write a file if there are any files that 
+ * start with that name and have an extension
+ * Please note, this is a blocking function.  Program execution will not return until ast_waitstream completes it's execution.
+ * Returns a struct ast_filestream on success, NULL on failure
+ */
+struct ast_filestream *ast_readfile(char *filename, char *type, char *comment, int oflags, int check, mode_t mode);
+
 //! Starts writing a file
 /*!
  * \param filename the name of the file to write to
@@ -261,6 +277,13 @@ int ast_stream_rewind(struct ast_filestream *fs, long ms);
  */
 long ast_tellstream(struct ast_filestream *fs);
 
+//! Read a frame from a filestream
+/*!
+ * \param ast_filestream fs to act on
+ * Returns a frame or NULL if read failed
+ */ 
+struct ast_frame *ast_readframe(struct ast_filestream *s);
+
 #define AST_RESERVED_POINTERS 20
 
 #if defined(__cplusplus) || defined(c_plusplus)
diff --git a/sounds.txt b/sounds.txt
index 86655bc47820aa1266b7ff95c2ace21a560959c3..71b5c1655625341e86769af6a1f5a0ec3e25943b 100755
--- a/sounds.txt
+++ b/sounds.txt
@@ -392,3 +392,5 @@
 
 %minutes.gsm%minutes
 
+%vm-forwardoptions.gsm%press 1 to prepend a message or 2 to forward the
+ message without prepending
diff --git a/sounds/vm-forwardoptions.gsm b/sounds/vm-forwardoptions.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..b9ccb7f98002c9b899db20eac904530744db273a
Binary files /dev/null and b/sounds/vm-forwardoptions.gsm differ