Index: apps/app_voicemail.c
===================================================================
--- apps/app_voicemail.c	(revision 95623)
+++ apps/app_voicemail.c	(working copy)
@@ -4629,6 +4629,8 @@
		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
 	else if (!strcasecmp(chan->language, "pt_BR"))
 		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL);
+	else if (!strcasecmp(chan->language, "he"))
+		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IM", NULL);
 	else if (!strcasecmp(chan->language, "tw"))      /* CHINESE (Taiwan) syntax */
 		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL);		
 	else
@@ -4810,17 +4790,42 @@
 	save_body(body, vms, "2", attachedfilefmt);
 
 	adsi_message(chan, vms);
-	if (!vms->curmsg)
-		res = wait_file2(chan, vms, "vm-first");	/* "First" */
-	else if (vms->curmsg == vms->lastmsg)
-		res = wait_file2(chan, vms, "vm-last");		/* "last" */
-
-	if (!res) {
-		res = wait_file2(chan, vms, "vm-message");	/* "message" */
-		if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
-			if (!res)
-				res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
+	if (!strcasecmp(chan->language, "he")) {	/* HEBREW FORMAT */
+		/*
+		 * Hebrew syntax is up side down here, which means that we first announce
+		 * the availability of a message, then its number
+		 */
+
+		if (!vms->curmsg) { 
+			res = wait_file2(chan, vms, "vm-message");
+			res = wait_file2(chan, vms, "vm-first");	/* "First" */
+		} else if (vms->curmsg == vms->lastmsg) {
+			res = wait_file2(chan, vms, "vm-message");
+			res = wait_file2(chan, vms, "vm-last");		/* "last" */
+		} else {
+			res = wait_file2(chan, vms, "vm-message");	/* "message" */
+			if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
+				ast_log(LOG_DEBUG, "curmsg: %s\n", vms->curmsg);
+				ast_log(LOG_DEBUG, "lagmsg: %s\n", vms->lastmsg);
+				if (!res) {
+					res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
+				}
+			}
 		}
+	} else {
+		if (!vms->curmsg) {
+			res = wait_file2(chan, vms, "vm-first");	/* "First" */
+		} else if (vms->curmsg == vms->lastmsg) {
+			res = wait_file2(chan, vms, "vm-last");		/* "last" */
+		}
+		if (!res) {
+			res = wait_file2(chan, vms, "vm-message");	/* "message" */
+			if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
+				if (!res) {
+					res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY,chan->language, (char *) NULL);
+				}
+			}
+		}
 	}
 
 	/* Get info from headers!! */
@@ -4891,13 +4941,20 @@
 	vms->starting = 0; 
 	make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
 	adsi_message(chan, vms);
-	if (!vms->curmsg)
-		res = wait_file2(chan, vms, "vm-first");	/* "First" */
-	else if (vms->curmsg == vms->lastmsg)
-		res = wait_file2(chan, vms, "vm-last");		/* "last" */
 	if (!res) {
-		/* POLISH syntax */
-		if (!strcasecmp(chan->language, "pl")) { 
+		if (!strcasecmp(chan->language, "he")) {
+			if (!vms->curmsg) {
+			    res = wait_file2(chan, vms, "vm-message");
+			    res = wait_file2(chan, vms, "vm-first");
+			} else if (vms->curmsg == vms->lastmsg) {
+			    res = wait_file2(chan, vms, "vm-message");
+			    res = wait_file2(chan, vms, "vm-last");
+			} else {
+			    res = wait_file2(chan, vms, "vm-message");
+			    res = wait_file2(chan, vms, "vm-number");
+			    res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
+			}
+		} else if (!strcasecmp(chan->language, "pl")) {
 			if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
 				int ten, one;
 				char nextmsg[256];
@@ -4918,17 +4986,27 @@
 					}
 				}
 			}
-			if (!res)
+			if (!res) {
 				res = wait_file2(chan, vms, "vm-message");
-		} else {
-			if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */
-				res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
-			else /* DEFAULT syntax */
-				res = wait_file2(chan, vms, "vm-message");
+			}
+		} else if (!strcasecmp(chan->language, "se")) {	/* SWEDISH syntax */
+			res = wait_file2(chan, vms, "vm-meddelandet");	/* message */
 			if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
-				if (!res)
-					res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
+				if (!res) {
+					res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
+				}
 			}
+		} else if (!strcasecmp(chan->language, "he")) {	/* HEBREW systax */
+			if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
+				if (!res) res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
+			}
+		} else {					/* ENGLISH syntax */
+			res = wait_file2(chan, vms, "vm-message");	/* message */
+			if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
+				if (!res) {
+					res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
+				}
+			}
 		}
 	}
 
@@ -5442,6 +5366,8 @@
 		return cmd ? cmd : ast_play_and_wait(chan, mbox);
 	} else if (!strcasecmp(chan->language, "gr")) {
 		return vm_play_folder_name_gr(chan, mbox);
+	} else if (!strcasecmp(chan->language, "he")) {
+		return vm_play_folder_name_gr(chan, mbox);
 	} else if (!strcasecmp(chan->language, "pl")) {
 		return vm_play_folder_name_pl(chan, mbox);
 	} else if (!strcasecmp(chan->language, "ua")) {  /* Ukrainian syntax */
@@ -5500,6 +5432,69 @@
 		res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
 	return res;
 }
+
+/* Hebrew syntax */
+static int vm_intro_he(struct ast_channel *chan, struct vm_state *vms)
+{
+	int res = 0;
+
+	/* Introduce messages they have */
+	if (!res) {
+		if ((vms->newmessages) || (vms->oldmessages)) {
+			res = ast_play_and_wait(chan, "vm-youhave");
+		}
+		if (vms->newmessages) {
+			if (!res) {
+				if (vms->newmessages == 1) {
+					res = ast_play_and_wait(chan, "vm-INBOX1");
+				} else {
+					if (vms->newmessages == 2) {
+						res = ast_play_and_wait(chan, "vm-shtei");
+					} else {
+						res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
+					}
+					res = ast_play_and_wait(chan, "vm-INBOX");
+				}
+			}
+			if (vms->oldmessages && !res) {
+				res = ast_play_and_wait(chan, "vm-and");
+				if (vms->oldmessages == 1) {
+					res = ast_play_and_wait(chan, "vm-Old1");
+				} else {
+					if (vms->oldmessages == 2) {
+						res = ast_play_and_wait(chan, "vm-shtei");
+					} else {
+						res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
+					}
+					res = ast_play_and_wait(chan, "vm-Old");
+				}
+			}
+		}
+		if (!res && vms->oldmessages && !vms->newmessages) {
+			if (!res) {
+				if (vms->oldmessages == 1) {
+					res = ast_play_and_wait(chan, "vm-Old1");
+				} else {
+					if (vms->oldmessages == 2) {
+						res = ast_play_and_wait(chan, "vm-shtei");
+					} else {
+						res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");					
+					}
+					res = ast_play_and_wait(chan, "vm-Old");
+				}
+			}
+		}
+		if (!res) {
+			if (!vms->oldmessages && !vms->newmessages) {
+				if (!res) {
+					res = ast_play_and_wait(chan, "vm-nomessages");
+				}
+			}
+		}
+	}
+	return res;
+}
+
 	
 /* Default English syntax */
 static int vm_intro_en(struct ast_channel *chan, struct vm_state *vms)
@@ -6328,6 +6290,8 @@
 		return vm_intro_ru(chan, vms);
 	} else if (!strcasecmp(chan->language, "ua")) { /* UKRAINIAN syntax */
 		return vm_intro_ua(chan, vms);
+	} else if (!strcasecmp(chan->language, "he")) {	/* HEBREW syntax */
+		return vm_intro_he(chan, vms);
 	} else {					/* Default to ENGLISH */
 		return vm_intro_en(chan, vms);
 	}
@@ -6341,8 +6310,14 @@
 		if (vms->starting) {
 			if (vms->lastmsg > -1) {
 				res = ast_play_and_wait(chan, "vm-onefor");
-				if (!res)
-					res = vm_play_folder_name(chan, vms->vmbox);
+				if (!res) {
+					if (!strcasecmp(chan->language, "he")) {
+						res = ast_play_and_wait(chan, "vm-for");
+						res = vm_play_folder_name(chan, vms->vmbox);
+					} else {
+						res = vm_play_folder_name(chan, vms->vmbox);
+					}
+				}
 			}
 			if (!res)
 				res = ast_play_and_wait(chan, "vm-opts");
@@ -6832,6 +6827,8 @@
 		return vm_browse_messages_it(chan, vms, vmu);
 	} else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) {	/* PORTUGUESE */
 		return vm_browse_messages_pt(chan, vms, vmu);
+	} else if (!strcasecmp(chan->language, "he")) {
+		return vm_browse_messages_he(chan, vms, vmu);	/* HEBREW */
 	} else if (!strcasecmp(chan->language, "gr")) {
 		return vm_browse_messages_gr(chan, vms, vmu);   /* GREEK */
 	} else if (!strcasecmp(chan->language, "tw")) {
@@ -7192,10 +7228,14 @@
 			}
 			if (useadsi)
 				adsi_status2(chan, &vms);
-				
-			if (!cmd)
-				cmd = vm_play_folder_name(chan, vms.vmbox);
 
+			if (!cmd) {
+				ast_log(LOG_DEBUG, "Language is now: %s \n", chan->language);
+				if (strcasecmp(chan->language, "he")) {
+					ast_log(LOG_DEBUG, "Playing back: %s\n", vms.vmbox);
+					cmd = vm_play_folder_name(chan, vms.vmbox);
+				}
+			}
 			vms.starting = 1;
 			break;
 		case '3': /* Advanced options */
Index: apps/app_zapscan.c
===================================================================
--- apps/app_zapscan.c	(revision 95623)
+++ apps/app_zapscan.c	(working copy)
@@ -349,7 +349,11 @@
 			}
 			confno = atoi(strchr(confstr,'/') + 1);
 			ast_stopstream(chan);
-			ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
+			if (!strcasecmp(chan->language, "he")) {
+			    ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, "f"); /* HEBREW SYNTAX */
+			} else {
+			    ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
+			}
 			res = conf_run(chan, confno, confflags);
 			if (res<0) break;
 			input = res;
Index: main/say.c
===================================================================
--- main/say.c	(revision 95623)
+++ main/say.c	(working copy)
@@ -353,6 +353,7 @@
 static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
 static int ast_say_enumeration_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
 static int ast_say_enumeration_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
+static int ast_say_enumeration_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
 
 /* Forward declarations of ast_say_date, ast_say_datetime and ast_say_time functions */
 static int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
@@ -363,6 +364,7 @@
 static int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_date_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+static int ast_say_date_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_date_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_date_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 
@@ -389,6 +388,7 @@
 static int ast_say_time_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_time_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+static int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_time_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 
@@ -401,6 +399,7 @@
 static int ast_say_datetime_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+static int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 
@@ -408,6 +408,7 @@
 static int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_from_now_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+static int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 
 static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang) 
 {
@@ -1181,48 +1172,87 @@
 
 
 /*! \brief  ast_say_number_full_he: Hebrew syntax */
-/* 	Extra sounds needed:
- 	1F: feminin 'one'
-	ve: 'and'
-	1hundred: 1 hundred
-	2hundred: 2 hundreds
-	2thousands: 2 thousand 
-	thousands: plural of 'thousand'
-	3sF 'Smichut forms (female)
-	4sF
-	5sF
-	6sF
-	7sF
-	8sF
-	9sF
-	3s 'Smichut' forms (male)
-	4s
-	5s
-	6s
-	7s
-	9s
-	10s
-	11s
-	12s
-	13s
-	14s
-	15s
-	16s
-	17s
-	18s
-	19s
-
-TODO: 've' should sometimed be 'hu':
-* before 'shtaym' (2, F)
-* before 'shnaym' (2, M)
-* before 'shlosha' (3, M)
-* before 'shmone' (8, M)
-* before 'shlosim' (30)
-* before 'shmonim' (80)
-
-What about:
-'sheva' (7, F)?
-'tesha' (9, F)?
+/*      Sounds files required for this to work correctly:
+0.gsm
+100.gsm
+100k.gsm
+10k.gsm
+1k.gsm
+1m.gsm
+2m.gsm
+200.gsm
+200k.gsm
+20.gsm
+2k.gsm
+300.gsm
+300k.gsm
+30.gsm
+3k.gsm
+400.gsm
+400k.gsm
+40.gsm
+4k.gsm
+500.gsm
+500k.gsm
+50.gsm
+5k.gsm
+600.gsm
+600k.gsm
+60.gsm
+6k.gsm
+700.gsm
+700k.gsm
+70.gsm
+7k.gsm
+800.gsm
+800k.gsm
+80.gsm
+8k.gsm
+900.gsm
+900k.gsm
+90.gsm
+9k.gsm
+f-01.gsm
+f-02.gsm
+f-03.gsm
+f-04.gsm
+f-05.gsm
+f-06.gsm
+f-07.gsm
+f-08.gsm
+f-09.gsm
+f-10.gsm
+f-11.gsm
+f-12.gsm
+f-13.gsm
+f-14.gsm
+f-15.gsm
+f-16.gsm
+f-17.gsm
+f-18.gsm
+f-19.gsm
+m-01.gsm
+m-02.gsm
+m-03.gsm
+m-04.gsm
+m-05.gsm
+m-06.gsm
+m-07.gsm
+m-08.gsm
+m-09.gsm
+m-10.gsm
+m-11.gsm
+m-12.gsm
+m-13.gsm
+m-14.gsm
+m-15.gsm
+m-16.gsm
+m-17.gsm
+m-18.gsm
+m-19.gsm
+minus.gsm
+uu.gsm
+ve.gsm
 */
 #define SAY_NUM_BUF_SIZE 256
 static int ast_say_number_full_he(struct ast_channel *chan, int num, 
@@ -1232,6 +1172,7 @@
 	int res = 0;
 	int state = 0; /* no need to save anything */
 	int mf = 1;    /* +1 = Masculin; -1 = Feminin */
+	int tmpnum = 0;
	char fn[SAY_NUM_BUF_SIZE] = "";
 	ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: started. "
 		"num: %d, options=\"%s\"\n",
@@ -1243,6 +1172,11 @@
	if (options && !strncasecmp(options, "f",1))
		mf = -1;
 
+	ast_debug(3, "%s: num: %d, "
+		"state=%d, options=\"%s\", mf=%d\n",
+		__FUNCTION__, num, state, options, mf
+	);
+
 	/* Do we have work to do? */
 	while (!res && (num || (state>0) ))  {
 		/* first type of work: play a second sound. In this loop
@@ -1255,68 +1172,135 @@
 		 * to check if the number num has yet anything left.
 		 */
		ast_debug(3, "ast_say_digits_full: num: %d, "
-			"state=%d, options=\"%s\", mf=%d\n",
+			"state=%d, options=\"%s\", mf=%d, tmpnum=%d\n",
-			num, state, options, mf
+			num, state, options, mf, tmpnum
 		);
 		if (state == 1) {
-			ast_copy_string(fn, "digits/hundred", sizeof(fn));
 			state = 0;
 		} else if (state == 2) {
-			ast_copy_string(fn, "digits/ve", sizeof(fn));
+			switch (num) {
+				/* We need to add Ve ("and") before a */
+				/* digit. The way it is pronounced    */
+				/* depends on the context             */
+				/* Intentional fallthroughs: */
+				case 1:
+			    	case 4:
+				case 5:
+				case 6:
+				case 7:
+				case 9:
+				case 10:
+					ast_copy_string(fn, "digits/ve", sizeof(fn));
+					break;
+				case 2:
+				case 8:
+					ast_copy_string(fn, "digits/uu", sizeof(fn));
+					break;
+			    	case 3:
+					if (mf < 0)
+					    ast_copy_string(fn, "digits/ve", sizeof(fn));
+					else
+					    ast_copy_string(fn, "digits/uu", sizeof(fn));
+					break;
+			}
 			state = 0;
 		} else if (state == 3) {
-			ast_copy_string(fn, "digits/thousands", sizeof(fn));
+			ast_copy_string(fn, "digits/1k", sizeof(fn));
 			state=0;
+		} else if (state == 4) {
+			if (mf < 0) {
+				ast_copy_string(fn, "digits/ve", sizeof(fn));
+			} else {
+				ast_copy_string(fn, "digits/uu", sizeof(fn));
+ 			}
+ 			state = 0;
+		} else if (num < 0) {
+			ast_copy_string(fn, "digits/minus", sizeof(fn));
+			num = (-1) * num;
-		} else if (num < 21) {
-			if (mf < 0)
-				snprintf(fn, sizeof(fn), "digits/%dF", num);
-			else
-				snprintf(fn, sizeof(fn), "digits/%d", num);
+		} else if (num <20) {
+			if (mf < 0) {
+				if (num < 10) {
+					snprintf(fn, sizeof(fn), "digits/f-0%d", num);
+				} else {
+					snprintf(fn, sizeof(fn), "digits/f-%d", num);
+				}
+			} else {
+				if (num < 10) {
+					snprintf(fn, sizeof(fn), "digits/m-0%d", num);
+				} else {
+					snprintf(fn, sizeof(fn), "digits/m-%d", num);
+				}
+			}
 			num = 0;
-		} else if (num < 100) {
+		} else if ((num < 100) && (num >= 20)) {
			snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
 			num = num % 10;
 			if (num > 0) state = 2;
-		} else if (num < 200) {
-			ast_copy_string(fn, "digits/1hundred", sizeof(fn));
-			num = num - 100;
-			state = 2;
-		} else if (num < 300) {
-			ast_copy_string(fn, "digits/2hundred", sizeof(fn));
-			num = num - 200;
-			state = 2;
-		} else if (num < 1000) {
-			snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
-			state = 1;
-			num = num % 100;
+		} else if ((num >= 100) && (num < 1000)) {
+				tmpnum = num/100;
+				snprintf(fn, sizeof(fn), "digits/%d00", tmpnum);
+				num = num - (tmpnum * 100);
+			if ((num > 0) && (num < 11)) {
+				state = 2;
+			} else if ((num >= 11) && (num < 21)) {
+				state = 4;
+			}
-		} else if (num < 2000) {
-			ast_copy_string(fn, "digits/thousand", sizeof(fn));
-			num = num - 1000;
-		} else if (num < 3000) {
-			ast_copy_string(fn, "digits/2thousand", sizeof(fn));
-			num = num - 2000;
-			if (num > 0)
-				state = 2;
+		} else if ((num >= 1000) && (num < 10000)) {
+			tmpnum = num / 1000;
+			snprintf(fn, sizeof(fn), "digits/%dk", tmpnum);
+			num = num - (tmpnum * 1000);
+			if ((num > 0) && (num < 11)) {
+				state = 2;
+			} else if ((num >= 11) && (num < 21)) {
+				state = 4;
+			}
 		} else if (num < 20000) {
-			snprintf(fn, sizeof(fn), "digits/%ds", (num / 1000));
+			snprintf(fn, sizeof(fn), "digits/m-%d", (num / 1000));
 			num = num % 1000;
 			state = 3;
 		} else if (num < 1000000) {
-			res = ast_say_number_full_he(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
+			res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd);
 			if (res)
 				return res;
 			ast_copy_string(fn, "digits/thousand", sizeof(fn));
 			num = num % 1000;
+			if ((num > 0) && (num < 11)) {
+				state = 2;
+			} else if ((num >= 11) && (num < 21)) {
+				state = 4;
+			}
+		} else if (num < 2000000) {
+			ast_copy_string(fn, "digits/1m", sizeof(fn));
+			num = num % 1000000;
+			if ((num > 0) && (num < 11)) {
+				state = 2;
+			} else if ((num >= 11) && (num < 21)) {
+				state = 4;
+			}
+		} else if (num < 3000000) {
+			ast_copy_string(fn, "digits/2m", sizeof(fn));
+			num = num - 2000000;
+			if ((num > 0) && (num < 11)) {
+				state = 2;
+			} else if ((num >= 11) && (num < 21)) {
+				state = 4;
+			}
 		} else	if (num < 1000000000) {
-			res = ast_say_number_full_he(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
+			res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd);
 			if (res)
 				return res;
-			ast_copy_string(fn, "digits/million", sizeof(fn));
+			ast_copy_string(fn, "digits/1m", sizeof(fn));
 			num = num % 1000000;
+			if ((num > 0) && (num < 11)) {
+				state = 2;
+			} else if ((num >= 11) && (num < 21)) {
+				state = 4;
+			}
 		} else {
			ast_debug(1, "Number '%d' is too big for me\n", num);
 			res = -1;
 		}
+		tmpnum = 0;
 		if (!res) {
 			if (!ast_streamfile(chan, fn, language)) {
 				if ((audiofd > -1) && (ctrlfd > -1))
@@ -2461,6 +2434,8 @@
 	   return(ast_say_enumeration_full_da(chan, num, ints, language, options, audiofd, ctrlfd));
 	} else if (!strcasecmp(language, "de") ) {	/* German syntax */
 	   return(ast_say_enumeration_full_de(chan, num, ints, language, options, audiofd, ctrlfd));
+	} else if (!strcasecmp(language, "he") ) {      /* Hebrew syntax */
+		return ast_say_enumeration_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
 	} 
 	
 	/* Default to english */
@@ -2892,6 +2867,102 @@
 	return res;
 }
 
+
+/*! \brief  ast_say_enumeration_full_he: Hebrew syntax */
+static int ast_say_enumeration_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
+{
+	int res = 0;
+	char fn[256] = "";
+        int mf = 1;    /* +1 = Masculin; -1 = Feminin */
+        ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: started. "
+                                     "num: %d, options=\"%s\"\n",
+                                     num, options);
+        
+        if (options && !strncasecmp(options, "f",1)) {
+                mf = -1;
+	}
+        
+        ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: num: %d, "
+                "options=\"%s\", mf=%d\n",
+                num, options, mf);
+	
+	while (!res && num) {
+		if (num < 0) {
+			snprintf(fn, sizeof(fn), "digits/minus"); /* kind of senseless for enumerations, but our best effort for error checking */
+			if ( num > INT_MIN ) {
+				num = -num;
+			} else {
+				num = 0;
+			}	
+		} else if (num < 21) {
+                        if (mf < 0) {
+		        	if (num < 10) {
+					snprintf(fn, sizeof(fn), "digits/f-0%d", num);
+				} else {
+					snprintf(fn, sizeof(fn), "digits/f-%d", num);
+				}
+			} else {
+				if (num < 10) {
+					snprintf(fn, sizeof(fn), "digits/m-0%d", num);
+				} else {
+					snprintf(fn, sizeof(fn), "digits/m-%d", num);
+				}
+			}
+			num = 0;
+		} else if ((num < 100) && num >=20) { 
+			snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
+			num = num % 10;
+		} else if ((num >= 100) && (num < 1000)) {
+			int tmpnum = num/100;
+			snprintf(fn, sizeof(fn), "digits/%d00", tmpnum);
+			num = num - (tmpnum * 100);
+		} else if ((num >= 1000) && (num < 10000)) {
+                        int tmpnum = num / 1000;
+			snprintf(fn, sizeof(fn), "digits/%dk", tmpnum);
+			num = num - (tmpnum * 1000);
+		} else if (num < 20000) {
+			snprintf(fn, sizeof(fn), "digits/m-%d",(num/1000));
+			num = num % 1000;
+		} else if (num < 1000000) {
+			res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd);
+			if (res) {
+				return res;
+			}
+			snprintf(fn, sizeof(fn), "digits/1k");
+			num = num % 1000;
+		} else if (num < 2000000) {
+			snprintf(fn, sizeof(fn), "digits/1m");
+			num = num % 1000000;
+		} else if (num < 3000000) {
+			snprintf(fn, sizeof(fn), "digits/2m");
+			num = num - 2000000;
+		} else if (num < 1000000000) {
+			res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd);
+			if (res) {
+				return res;
+			}
+			snprintf(fn, sizeof(fn), "digits/1m");
+			num = num % 1000000;
+		} else {
+			ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
+			res = -1;
+		}
+
+		if (!res) {
+			if (!ast_streamfile(chan, fn, language)) {
+				if ((audiofd > -1) && (ctrlfd > -1)) {
+					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+				} else {
+					res = ast_waitstream(chan, ints);
+				}
+			}
+			ast_stopstream(chan);
+		}
+	}
+	return res;
+}
+
+
 static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 {
 	if (!strcasecmp(lang, "en") ) {	/* English syntax */
@@ -2914,6 +2981,8 @@
 		return(ast_say_date_gr(chan, t, ints, lang));
 	} else if (!strcasecmp(lang, "ge") ) {  /* Georgian syntax */
 		return(ast_say_date_ge(chan, t, ints, lang));
+	} else if (!strcasecmp(lang, "he") ) {  /* Hebrew  Syntax*/
+		return (ast_say_date_he(chan, t, ints, lang));
	}
 
 	/* Default to English */
@@ -3201,6 +3196,40 @@
 	return res;
 }
 
+/* Hebrew syntax */
+int ast_say_date_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+	struct tm tm;
+	char fn[256];
+	int res = 0;
+	ast_localtime(&t,&tm,NULL);
+	if (!res) {
+		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+		res = ast_streamfile(chan, fn, lang);
+		if (!res) {
+			res = ast_waitstream(chan, ints);
+		}
+	}
+	if (!res) {
+		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+		res = ast_streamfile(chan, fn, lang);
+		if (!res) {
+			res = ast_waitstream(chan, ints);
+		}
+	}
+	if (!res) {
+		res = ast_say_number(chan, tm.tm_mday, ints, lang, "m");
+	}
+	if (!res) {
+		res = ast_waitstream(chan, ints);
+	}
+	if (!res) {
+		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "m");
+	}
+	return res;
+}
+
+
 static int say_date_with_format(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
 {
 	if (!strcasecmp(lang, "en") ) {	/* English syntax */
@@ -4067,8 +3933,8 @@
  * * The numbers of 3000--19000 are not handled well
  **/
 #define IL_DATE_STR "AdBY"
-#define IL_TIME_STR "IMp"
-#define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
+#define IL_TIME_STR "HM" /* NOTE: In Hebrew we do not support 12 hours, only 24. No AM or PM exists in the Hebrew language */
+#define IL_DATE_STR_FULL IL_DATE_STR IL_TIME_STR
 int ast_say_date_with_format_he(struct ast_channel *chan, time_t time, 
     const char *ints, const char *lang, const char *format, 
     const char *timezone)
@@ -4119,37 +3996,19 @@
 				res = ast_say_number_full_he(chan, tm.tm_year + 1900, ints, lang, "f", -1, -1);
 				break;
 			case 'I':
-			case 'l': /* 12-Hour */
-				{
-					int hour = tm.tm_hour;
-					hour = hour % 12;
-					if (hour == 0)
-						hour = 12;
-				
-					res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1);
-				}
-				break;
+			case 'l': /* 12-Hour -> we do not support 12 hour based langauges in Hebrew */
 			case 'H':
 			case 'k': /* 24-Hour */
-				/* With 'H' there is an 'oh' after a single-
-				 * digit hour */
-				if ((format[offset] == 'H') && (tm.tm_hour < 10) && (tm.tm_hour > 0)) { /* e.g. oh-eight */
-					res = wait_file(chan, ints, "digits/oh", lang);
-				}
-				
				res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1);
 				break;
 			case 'M': /* Minute */
+                                if (tm.tm_min >= 0 && tm.tm_min <= 9) /* say a leading zero if needed */
+					res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1,-1);
 				res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
 				break;
 			case 'P':
 			case 'p':
-				/* AM/PM */
-				if (tm.tm_hour > 11)
-					ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
-				else
-					ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
-				res = wait_file(chan, ints, nextmsg, lang);
+				/* AM/PM - There is no AM/PM in Hebrew... */ 
 				break;
 			case 'Q':
 				/* Shorthand for "Today", "Yesterday", or "date" */
@@ -5843,6 +5726,8 @@
 		return(ast_say_time_gr(chan, t, ints, lang));
 	} else if (!strcasecmp(lang, "ge") ) {  /* Georgian syntax */
 		return(ast_say_time_ge(chan, t, ints, lang));
+	} else if (!strcasecmp(lang, "he") ) {  /* Hebrew syntax */
+		return(ast_say_time_he(chan, t, ints, lang));
	}
 
 	/* Default to English */
@@ -6099,6 +5936,41 @@
 	return res;
 }
 
+/* Hebrew syntax */
+int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+	struct tm tm;
+	int res = 0;
+	int hour;
+
+	ast_localtime(&t, &tm, NULL);
+	hour = tm.tm_hour;
+	if (!hour)
+		hour = 12;
+        
+	if (!res)
+		res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1);
+
+	if (tm.tm_min > 9) {
+		if (!res)
+			res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
+	} else if (tm.tm_min) {
+               if (!res) { /* say a leading zero if needed */ 
+                        res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);        
+               }
+		if (!res)
+			res = ast_waitstream(chan, ints);
+		if (!res)
+			res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
+	} else {
+		if (!res)
+			res = ast_waitstream(chan, ints);
+	}
+	if (!res)
+		res = ast_waitstream(chan, ints);
+	return res;
+}
+
 static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 {
 	if (!strcasecmp(lang, "en") ) {	/* English syntax */
@@ -6123,6 +5991,8 @@
 		return(ast_say_datetime_gr(chan, t, ints, lang));
 	} else if (!strcasecmp(lang, "ge") ) {  /* Georgian syntax */
 		return(ast_say_datetime_ge(chan, t, ints, lang));
+	} else if (!strcasecmp(lang, "he") ) { /* Hebrew syntax */
+                return(ast_say_datetime_he(chan, t, ints, lang));
	}
 
 	/* Default to English */
@@ -6469,6 +6276,73 @@
 	return res;
 }
 
+/* Hebrew syntax */
+int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+	struct tm tm;
+	char fn[256];
+	int res = 0;
+	int hour;
+
+	ast_localtime(&t, &tm, NULL);
+	if (!res) {
+		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+		res = ast_streamfile(chan, fn, lang);
+		if (!res) {
+			res = ast_waitstream(chan, ints);
+		}
+	}
+	if (!res) {
+		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+		res = ast_streamfile(chan, fn, lang);
+		if (!res) {
+			res = ast_waitstream(chan, ints);
+		}
+	}
+	if (!res) {
+		res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
+	}
+
+	hour = tm.tm_hour;
+	if (!hour) {
+		hour = 12;
+	}
+
+	if (!res) {
+		res = ast_say_number(chan, hour, ints, lang, "f");
+	}
+
+	if (tm.tm_min > 9) {
+		if (!res) {
+			res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
+		}
+	} else if (tm.tm_min) {
+                if (!res) {
+                         /* say a leading zero if needed */
+                        res = ast_say_number(chan, 0, ints, lang, "f");
+                }
+		if (!res) {
+			res = ast_waitstream(chan, ints);
+		}
+		if (!res) {
+			res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
+		}
+	} else {
+		if (!res) {
+			res = ast_waitstream(chan, ints);
+		}
+	}
+
+	if (!res) {
+		res = ast_waitstream(chan, ints);
+	}
+	if (!res) {
+		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "f");
+	}
+	return res;
+}
+
+
 static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 {
 	if (!strcasecmp(lang, "en") ) {	/* English syntax */
@@ -6479,7 +6353,9 @@
 		return(ast_say_datetime_from_now_pt(chan, t, ints, lang));
 	} else if (!strcasecmp(lang, "ge") ) {	/* Georgian syntax */
 		return(ast_say_datetime_from_now_ge(chan, t, ints, lang));
+	} else if(!strcasecmp(lang, "he") ) { /* Hebrew syntax */
+                return(ast_say_datetime_from_now_he(chan, t, ints, lang));
	}
 
 	/* Default to English */
 	return(ast_say_datetime_from_now_en(chan, t, ints, lang));
@@ -6611,7 +6493,49 @@
 	return res;
 }
 
+/* Hebrew syntax */
+int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+	int res=0;
+	time_t nowt;
+	int daydiff;
+	struct tm tm;
+	struct tm now;
+	char fn[256];
 
+	time(&nowt);
+
+	ast_localtime(&t, &tm, NULL);
+	ast_localtime(&nowt,&now, NULL);
+	daydiff = now.tm_yday - tm.tm_yday;
+	if ((daydiff < 0) || (daydiff > 6)) {
+		/* Day of month and month */
+		if (!res) {
+			snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+			res = ast_streamfile(chan, fn, lang);
+			if (!res)
+				res = ast_waitstream(chan, ints);
+		}
+		if (!res) {
+			res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
+		}
+	} else if (daydiff) {
+		/* Just what day of the week */
+		if (!res) {
+			snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+			res = ast_streamfile(chan, fn, lang);
+			if (!res) {
+				res = ast_waitstream(chan, ints);
+			}
+		}
+	} /* Otherwise, it was today */
+	if (!res) {
+		res = ast_say_time(chan, t, ints, lang);
+	}
+	return res;
+}
+
+
 /*********************************** GREEK SUPPORT ***************************************/
 
 
