diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index 65f6e1812d..42eede31ee 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -52,14 +52,12 @@
     <X-PRE-PROCESS cmd="include" data="directory/*.xml"/>
   </section>
 
-  <!-- phrases section (under development still) -->
-  <section name="phrases" description="Speech Phrase Management">
-    <macros>
-      <X-PRE-PROCESS cmd="include" data="lang/de/*.xml"/>
-      <X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
-      <X-PRE-PROCESS cmd="include" data="lang/fr/*.xml"/>
-      <X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
-      <X-PRE-PROCESS cmd="include" data="lang/he/*.xml"/>
-    </macros>
+  <!-- languages section (under development still) -->
+  <section name="languages" description="Language Management">
+    <X-PRE-PROCESS cmd="include" data="lang/de/*.xml"/>
+    <X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
+    <X-PRE-PROCESS cmd="include" data="lang/fr/*.xml"/>
+    <X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
+    <X-PRE-PROCESS cmd="include" data="lang/he/*.xml"/>
   </section>
 </document>
diff --git a/conf/lang/de/de.xml b/conf/lang/de/de.xml
index 5239489f75..1b44c9a1dd 100644
--- a/conf/lang/de/de.xml
+++ b/conf/lang/de/de.xml
@@ -1,7 +1,11 @@
 <include>
-  <language name="de" sound-path="/snds" tts-engine="cepstral" tts-voice="david">
-    <X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
-    <!--voicemail_de_tts is purely implemented with tts, we need a files based implementation too -->
-    <X-PRE-PROCESS cmd="include" data="vm/tts.xml"/>
+  <language name="de" sound-prefix="/snds" tts-engine="cepstral" tts-voice="david">
+    <phrases>
+      <macros>
+        <X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
+        <!--voicemail_de_tts is purely implemented with tts, we need a files based implementation too -->
+        <X-PRE-PROCESS cmd="include" data="vm/tts.xml"/>
+      </macros>
+    </phrases>
   </language>
 </include>
diff --git a/conf/lang/en/en.xml b/conf/lang/en/en.xml
index 6bd5a7d5fb..1e23dc5d7b 100644
--- a/conf/lang/en/en.xml
+++ b/conf/lang/en/en.xml
@@ -1,8 +1,12 @@
 <include>
-  <language name="en" sound-path="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
-    <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
-    <!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
-    <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>  <!-- vm/tts.xml if you want to use tts and have cepstral -->
-    <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>  <!-- dir/tts.xml if you want to use tts and have cepstral -->
+  <language name="en" say-module="en" sound-prefix="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
+    <phrases>
+      <macros>
+        <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
+        <!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
+        <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>  <!-- vm/tts.xml if you want to use tts and have cepstral -->
+        <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>  <!-- dir/tts.xml if you want to use tts and have cepstral -->
+      </macros>
+    </phrases>
   </language>
 </include>
diff --git a/conf/lang/fr/fr.xml b/conf/lang/fr/fr.xml
index 12bec06f20..eaf00f247e 100644
--- a/conf/lang/fr/fr.xml
+++ b/conf/lang/fr/fr.xml
@@ -1,8 +1,12 @@
 <include>
-  <language name="fr" sound-path="/snds" tts-engine="cepstral" tts-voice="david">
-    <X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
-    <!--voicemail_fr_tts is purely implemented with tts, we need a files based implementation too -->
-	<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
-	<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>  <!-- dir/tts.xml if you want to use tts and have cepstral -->
+  <language name="fr" say-module="fr" sound-prefix="$${sounds_dir}/fr/ca/june" tts-engine="cepstral" tts-voice="david">
+    <phrases>
+      <macros>
+        <X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
+        <!--voicemail_fr_tts is purely implemented with tts, we need a files based implementation too -->
+        <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
+        <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>  <!-- dir/tts.xml if you want to use tts and have cepstral -->
+      </macros>
+    </phrases>
   </language>
 </include>
diff --git a/conf/lang/he/he.xml b/conf/lang/he/he.xml
index 006195bf9a..fe7c5d8a01 100644
--- a/conf/lang/he/he.xml
+++ b/conf/lang/he/he.xml
@@ -1,7 +1,11 @@
 <include>
-  <language name="he" sound-path="$${sounds_dir}/he/daniel" tts-engine="cepstral" tts-voice="daniel">
-    <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
-    <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
-    <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>
+  <language name="he" sound-prefix="$${sounds_dir}/he/daniel" tts-engine="cepstral" tts-voice="daniel">
+    <phrases>
+      <macros>
+        <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
+        <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
+        <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>
+      </macros>
+    </phrases>
   </language>
 </include>
diff --git a/conf/lang/ru/ru.xml b/conf/lang/ru/ru.xml
index 25d63b6110..686e840860 100644
--- a/conf/lang/ru/ru.xml
+++ b/conf/lang/ru/ru.xml
@@ -1,9 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--тестовые файлы Вы звуковые файлы можно взять тут svn co http://svn.freeswitch.ru/bbv/mod_say_ru/ru/  -->
 <include>
-  <language name="ru" sound-path="$${sounds_dir}/ru/RU/elena" tts-engine="cepstral" tts-voice="elena">
-    <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
-    <!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
-    <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>  <!-- vm/tts.xml if you want to use tts and have cepstral -->
+  <language name="ru" sound-prefix="$${sounds_dir}/ru/RU/elena" tts-engine="cepstral" tts-voice="elena">
+    <phrases>
+      <macros>
+        <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
+        <!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
+        <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>  <!-- vm/tts.xml if you want to use tts and have cepstral -->
+      </macros>
+    </phrases>
   </language>
 </include>
diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h
index f1164cee2e..2d3f994878 100644
--- a/src/include/switch_xml.h
+++ b/src/include/switch_xml.h
@@ -417,6 +417,8 @@ SWITCH_DECLARE(switch_xml_section_t) switch_xml_parse_section_string(_In_opt_z_
 
 SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond);
 
+SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language);
+
 SWITCH_END_EXTERN_C
 ///\}
 #endif // _SWITCH_XML_H
diff --git a/src/mod/applications/mod_protovm/protovm.conf.xml b/src/mod/applications/mod_protovm/protovm.conf.xml
index 3c42ce1faa..e25b8760c8 100644
--- a/src/mod/applications/mod_protovm/protovm.conf.xml
+++ b/src/mod/applications/mod_protovm/protovm.conf.xml
@@ -17,7 +17,7 @@
 		<menus>
 			<menu name="std_authenticate">
 			<phrases>
-				<phrase name="fail_auth" value="protovm_fail_auth" />
+				<phrase name="fail_auth" value="fail_auth@protovm" />
 			</phrases>
 			<keys>
 			</keys>
@@ -25,7 +25,7 @@
 
 			<menu name="std_authenticate_ask_user">
 			<phrases>
-				<phrase name="instructions" value="protovm_enter_id" />
+				<phrase name="instructions" value="enter_id@protovm" />
 			</phrases>
 			<keys>
 				<key dtmf="#" action="ivrengine:terminate_entry" variable="VM-Key-Terminator" /> <!-- TODO Make the ivrengine: parsed and the key configurable -->
@@ -34,7 +34,7 @@
 
 			<menu name="std_authenticate_ask_password">
 			<phrases>
-				<phrase name="instructions" value="protovm_enter_pass" />
+				<phrase name="instructions" value="enter_pass@protovm" />
 			</phrases>
 			<keys>
 				<key dtmf="#" action="ivrengine:terminate_entry" variable="VM-Key-Terminator" /> <!-- TODO Make the ivrengine: parsed and the key configurable -->
@@ -43,12 +43,12 @@
 
 			<menu name="std_navigator">
 			<phrases>
-				<phrase name="msg_count" value="protovm_message_count" />
-				<phrase name="say_date" value="protovm_say_date_event" />
-				<phrase name="say_msg_number" value="protovm_say_message_number" />
-				<phrase name="menu_options" value="protovm_listen_file_check" />
-				<phrase name="ack" value="protovm_ack" />
-				<phrase name="play_message" value="protovm_play_message" />
+				<phrase name="msg_count" value="message_count@protovm" />
+				<phrase name="say_date" value="say_date_event@protovm" />
+				<phrase name="say_msg_number" value="say_message_number@protovm" />
+				<phrase name="menu_options" value="listen_file_check@protovm" />
+				<phrase name="ack" value="ack@protovm" />
+				<phrase name="play_message" value="play_message@protovm" />
 			</phrases>
 			<keys>
 				<key dtmf="1" action="skip_intro" variable="VM-Key-Main-Listen-File" />
@@ -62,7 +62,7 @@
 
 			<menu name="std_preference">
 			<phrases>
-				<phrase name="menu_options" value="protovm_config_menu" />
+				<phrase name="menu_options" value="config_menu@protovm" />
 			</phrases>
 			<keys>
 				<key dtmf="1" action="menu:std_record_greeting_with_slot" variable="VM-Key-Record-Greeting" />
@@ -75,9 +75,9 @@
 
 			<menu name="std_record_greeting">
 			<phrases>
-				<phrase name="instructions" value="voicemail_record_greeting" />
-				<phrase name="play_recording" value="protovm_play_recording" />
-				<phrase name="menu_options" value="protovm_record_file_check" />
+				<phrase name="instructions" value="record_greeting@protovm" />
+				<phrase name="play_recording" value="play_recording@protovm" />
+				<phrase name="menu_options" value="record_file_check@protovm" />
 			</phrases>
 			<keys>
 				<key dtmf="1" action="listen" variable="VM-Key-Listen-File" />
@@ -90,9 +90,9 @@
 
 			<menu name="std_record_name">
 			<phrases>
-				<phrase name="instructions" value="protovm_record_name" />
-				<phrase name="play_recording" value="protovm_play_recording" />
-				<phrase name="menu_options" value="protovm_record_file_check" />
+				<phrase name="instructions" value="record_name@protovm" />
+				<phrase name="play_recording" value="play_recording@protovm" />
+				<phrase name="menu_options" value="record_file_check@protovm" />
 			</phrases>
 			<keys>
 				<key dtmf="1" action="listen" variable="VM-Key-Listen-File" />
@@ -106,9 +106,9 @@
 
 			<menu name="std_select_greeting_slot">
 			<phrases>
-				<phrase name="instructions" value="protovm_choose_greeting" />
-				<phrase name="invalid_slot" value="protovm_choose_greeting_fail" />
-				<phrase name="selected_slot" value="protovm_greeting_selected" />
+				<phrase name="instructions" value="choose_greeting@protovm" />
+				<phrase name="invalid_slot" value="choose_greeting_fail@protovm" />
+				<phrase name="selected_slot" value="greeting_selected@protovm" />
 			</phrases>
 			<keys>
 			</keys>
@@ -116,7 +116,7 @@
 
 			<menu name="std_record_greeting_with_slot">
 			<phrases>
-				<phrase name="instructions" value="protovm_choose_greeting" />
+				<phrase name="instructions" value="choose_greeting@protovm" />
 			</phrases>
 			<keys>
 			</keys>
@@ -124,7 +124,7 @@
 
 			<menu name="std_set_password">
 			<phrases>
-				<phrase name="instructions" value="protovm_enter_pass" />
+				<phrase name="instructions" value="enter_pass@protovm" />
 			</phrases>
 			<keys>
 			</keys>
diff --git a/src/mod/applications/mod_protovm/sounds.xml b/src/mod/applications/mod_protovm/sounds.xml
index 2fe42a40d2..1760e7cc07 100644
--- a/src/mod/applications/mod_protovm/sounds.xml
+++ b/src/mod/applications/mod_protovm/sounds.xml
@@ -1,375 +1,376 @@
 <include><!--This line will be ignored it's here to validate the xml and is optional -->
-  <macro name="protovm_press_key">
-    <input pattern="^(.*):(.*)$">
-      <match>
-	<action function="play-file" data="$2"/>
-	<action function="play-file" data="voicemail/vm-press.wav"/>
-	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_plurial_msg">
-    <input pattern="^[01]:(.*):(.*)$" break_on_match="true">
-      <match>
-	<action function="play-file" data="$1"/>
-      </match>
-    </input>
-    <input pattern="^.*:(.*):(.*)$" break_on_match="true">
-      <match>
-	<action function="play-file" data="$2"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_enter_id">
-    <input pattern="(.+)">
-      <match>
-	<action function="play-file" data="voicemail/vm-enter_id.wav"/>
-	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
-      </match>
-      <nomatch>
-	<action function="play-file" data="voicemail/vm-enter_id.wav"/>
-	<action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
-      </nomatch>
-  </input>
-  </macro>
+  <macros name="protovm" sound-prefix="$${sounds_dir}/fr/ca/june"> 
+    <macro name="press_key">
+      <input pattern="^(.*):(.*)$">
+        <match>
+  	<action function="play-file" data="$2"/>
+  	<action function="play-file" data="voicemail/vm-press.wav"/>
+  	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
+        </match>
+      </input>
+    </macro>
   
-
-  <macro name="protovm_enter_pass">
-    <input pattern="(.+)">
-      <match>
-	<action function="play-file" data="voicemail/vm-enter_pass.wav"/>
-	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
-      </match>
-      <nomatch>
-	<action function="play-file" data="voicemail/vm-enter_pass.wav"/>
-	<action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
-      </nomatch>
-
-    </input>
-  </macro>
-
-  <macro name="protovm_fail_auth">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-fail_auth.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_hello">
-    <input>
-      <match>
-	<!--<action function="play-file" data="voicemail/vm-hello.wav"/> -->
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_goodbye">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-goodbye.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_abort">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-abort.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_message_count">
-    <input field="${VM-Total-New-Urgent-Messages}" pattern="^(0)$">
-      <nomatch>
-	<action function="play-file" data="voicemail/vm-you_have.wav"/>
-	<action function="say" data="${VM-Total-New-Urgent-Messages}" method="pronounced" type="items"/>
-	<action function="play-file" data="voicemail/vm-urgent-new.wav"/>
-	<action function="phrase" phrase="voicemail_plurial_msg" data="${VM-Total-New-Urgent-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
-      </nomatch>
-    </input>
-    <input field="${VM-Total-New-Messages}" pattern="^(\d+)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-you_have.wav"/>
-	<action function="say" data="${VM-Total-New-Messages}" method="pronounced" type="items"/>
-	<action function="play-file" data="voicemail/vm-new.wav"/>
-	<action function="phrase" phrase="voicemail_plurial_msg" data="${VM-Total-New-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
-      </match>
-    </input>
-    <input field="${VM-Total-Saved-Messages}" pattern="^(0)$">
-      <nomatch>
-	<action function="play-file" data="currency/and.wav"/>
-	<action function="say" data="${VM-Total-Saved-Messages}" method="pronounced" type="items"/>
-	<action function="play-file" data="voicemail/vm-saved.wav"/>
-	<action function="phrase" phrase="voicemail_plurial_msg" data="${VM-Total-Saved-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
-      </nomatch>
-    </input>
-  </macro>
-
-  <macro name="protovm_menu">
-    <input>
-      <match>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Play-New-Messages}:voicemail/vm-listen_new.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Play-Saved-Messages}:voicemail/vm-listen_saved.wav"/>	
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Config-Menu}:voicemail/vm-advanced.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Terminator}:voicemail/vm-to_exit.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_config_menu">
-    <input>
-      <match>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Record-Greeting}:voicemail/vm-to_record_greeting.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Choose-Greeting}:voicemail/vm-choose_greeting.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Record-Name}:voicemail/vm-record_name2.wav"/>	
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Change-Password}:voicemail/vm-change_password.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Menu}:voicemail/vm-main_menu.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_record_name">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-record_name1.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_record_file_check">
-    <input>
-      <match>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Save-File}:voicemail/vm-save_recording.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Record-File}:voicemail/vm-rerecord.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_record_urgent_check">
-    <input>
-      <match>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Urgent}:voicemail/vm-mark-urgent.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Terminator}:voicemail/vm-continue.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_forward_prepend">
-    <input>
-      <match>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Prepend}:voicemail/vm-forward_add_intro.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Forward}:voicemail/vm-send_message_now.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_forward_message_enter_extension">
-    <input pattern="^([0-9#*])$">
-      <match>
-	<action function="play-file" data="voicemail/vm-forward_enter_ext.wav"/>
-	<action function="play-file" data="voicemail/vm-followed_by.wav"/>
-	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_invalid_extension">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-that_was_an_invalid_ext.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_listen_file_check">
-    <input>
-      <match>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Next-Msg}:voicemail/vm-for_next_msg.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Save-File}:voicemail/vm-save_recording.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Delete-File}:voicemail/vm-delete_recording.wav"/>
-     </match>
-    </input>
-    <input field="${VM-Message-Email}" pattern="^$">
-      <nomatch>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Email}:voicemail/vm-forward_to_email.wav"/>
-      </nomatch>
-    </input>
-    <input>
-      <match>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Callback}:voicemail/vm-return_call.wav"/>
-	<action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Forward}:voicemail/vm-to_forward.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_choose_greeting">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-choose_greeting_choose.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_choose_greeting_fail">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-choose_greeting_fail.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_record_greeting">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-record_greeting.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_record_message">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-record_message.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_greeting_selected">
-    <input pattern="^(\d+)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-greeting.wav"/>
-	<action function="say" data="$1" method="pronounced" type="items"/>
-	<action function="play-file" data="voicemail/vm-selected.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_play_greeting">
-    <input pattern="^(.*)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-person.wav"/>
-	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
-	<action function="play-file" data="voicemail/vm-not_available.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_say_number">
-    <input pattern="^(\d+)$">
-      <match>
-	<action function="say" data="$1" method="pronounced" type="items"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_say_message_number">
-    <input>
-      <match>
-	<action function="play-file" data="voicemail/vm-${VM-Message-Type}.wav"/> 
-	<action function="play-file" data="voicemail/vm-message_number.wav"/>
-	<action function="say" data="${VM-Message-Number}" method="pronounced" type="items"/> 
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_say_phone_number">
-    <input pattern="^(.*)$">
-      <match>
-	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_say_name">
-    <input pattern="^(.*)$">
-      <match>
-	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
-      </match>
-    </input>
-  </macro>
-  <!-- Note: Update this to marked-urgent,emailed and saved once new sound files are recorded -->
-  <macro name="protovm_ack"> 
-    <input pattern="^(too-small)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-too-small.wav"/>
-      </match>
-    </input>
-    <input pattern="^(undeleted)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-message.wav"/>
-	<action function="play-file" data="voicemail/vm-$1.wav"/>
-      </match>
-    </input>
-    <input pattern="^(deleted)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-message.wav"/>
-	<action function="play-file" data="voicemail/vm-$1.wav"/>
-      </match>
-    </input>
-    <input pattern="^(saved)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-message.wav"/>
-	<action function="play-file" data="voicemail/vm-$1.wav"/>
-      </match>
-    </input>
-    <input pattern="^(emailed)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-message.wav"/>
-	<action function="play-file" data="voicemail/vm-$1.wav"/>
-      </match>
-    </input>
-    <input pattern="^(marked-urgent)$">
-      <match>
-	<action function="play-file" data="voicemail/vm-message.wav"/>
-	<action function="play-file" data="voicemail/vm-$1.wav"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_say_date">
-    <input pattern="^(.*)$">
-      <match>
-	<action function="say" data="$1" method="pronounced" type="short_date_time"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_say_date_event">
-    <input>
-      <match>
-        <action function="say" data="${VM-Message-Received-Epoch}" method="pronounced" type="short_date_time"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_play_message">
-    <input>
-      <match>
-        <action function="play-file" data="${VM-Message-File-Path}"/>
-      </match>
-    </input>
-  </macro>
-
-  <macro name="protovm_play_recording">
-    <input>
-      <match>
-        <action function="play-file" data="${VM-Record-File-Path}"/>
-      </match>
-    </input>
-  </macro>
+    <macro name="plurial_msg">
+      <input pattern="^[01]:(.*):(.*)$" break_on_match="true">
+        <match>
+  	<action function="play-file" data="$1"/>
+        </match>
+      </input>
+      <input pattern="^.*:(.*):(.*)$" break_on_match="true">
+        <match>
+  	<action function="play-file" data="$2"/>
+        </match>
+      </input>
+    </macro>
   
-  <macro name="protovm_disk_quota_exceeded">
-    <input>
-	<match>
-	    <action function="play-file" data="voicemail/vm-mailbox_full.wav"/>
-	</match>
+    <macro name="enter_id">
+      <input pattern="(.+)">
+        <match>
+  	<action function="play-file" data="voicemail/vm-enter_id.wav"/>
+  	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
+        </match>
+        <nomatch>
+  	<action function="play-file" data="voicemail/vm-enter_id.wav"/>
+  	<action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
+        </nomatch>
     </input>
-  </macro>
-
+    </macro>
+    
+  
+    <macro name="enter_pass">
+      <input pattern="(.+)">
+        <match>
+  	<action function="play-file" data="voicemail/vm-enter_pass.wav"/>
+  	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
+        </match>
+        <nomatch>
+  	<action function="play-file" data="voicemail/vm-enter_pass.wav"/>
+  	<action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
+        </nomatch>
+  
+      </input>
+    </macro>
+  
+    <macro name="fail_auth">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-fail_auth.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="hello">
+      <input>
+        <match>
+  	<!--<action function="play-file" data="voicemail/vm-hello.wav"/> -->
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="goodbye">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-goodbye.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="abort">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-abort.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="message_count">
+      <input field="${VM-Total-New-Urgent-Messages}" pattern="^(0)$">
+        <nomatch>
+  	<action function="play-file" data="voicemail/vm-you_have.wav"/>
+  	<action function="say" data="${VM-Total-New-Urgent-Messages}" method="pronounced" type="items"/>
+  	<action function="play-file" data="voicemail/vm-urgent-new.wav"/>
+  	<action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-New-Urgent-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
+        </nomatch>
+      </input>
+      <input field="${VM-Total-New-Messages}" pattern="^(\d+)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-you_have.wav"/>
+  	<action function="say" data="${VM-Total-New-Messages}" method="pronounced" type="items"/>
+  	<action function="play-file" data="voicemail/vm-new.wav"/>
+  	<action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-New-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
+        </match>
+      </input>
+      <input field="${VM-Total-Saved-Messages}" pattern="^(0)$">
+        <nomatch>
+  	<action function="play-file" data="currency/and.wav"/>
+  	<action function="say" data="${VM-Total-Saved-Messages}" method="pronounced" type="items"/>
+  	<action function="play-file" data="voicemail/vm-saved.wav"/>
+  	<action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-Saved-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
+        </nomatch>
+      </input>
+    </macro>
+  
+    <macro name="menu">
+      <input>
+        <match>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Play-New-Messages}:voicemail/vm-listen_new.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Play-Saved-Messages}:voicemail/vm-listen_saved.wav"/>	
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Config-Menu}:voicemail/vm-advanced.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Terminator}:voicemail/vm-to_exit.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="config_menu">
+      <input>
+        <match>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-Greeting}:voicemail/vm-to_record_greeting.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Choose-Greeting}:voicemail/vm-choose_greeting.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-Name}:voicemail/vm-record_name2.wav"/>	
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Change-Password}:voicemail/vm-change_password.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Menu}:voicemail/vm-main_menu.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="record_name">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-record_name1.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="record_file_check">
+      <input>
+        <match>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Save-File}:voicemail/vm-save_recording.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-File}:voicemail/vm-rerecord.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="record_urgent_check">
+      <input>
+        <match>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Urgent}:voicemail/vm-mark-urgent.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Terminator}:voicemail/vm-continue.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="forward_prepend">
+      <input>
+        <match>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Prepend}:voicemail/vm-forward_add_intro.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Forward}:voicemail/vm-send_message_now.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="forward_message_enter_extension">
+      <input pattern="^([0-9#*])$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-forward_enter_ext.wav"/>
+  	<action function="play-file" data="voicemail/vm-followed_by.wav"/>
+  	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="invalid_extension">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-that_was_an_invalid_ext.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="listen_file_check">
+      <input>
+        <match>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Next-Msg}:voicemail/vm-for_next_msg.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Save-File}:voicemail/vm-save_recording.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Delete-File}:voicemail/vm-delete_recording.wav"/>
+       </match>
+      </input>
+      <input field="${VM-Message-Email}" pattern="^$">
+        <nomatch>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Email}:voicemail/vm-forward_to_email.wav"/>
+        </nomatch>
+      </input>
+      <input>
+        <match>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Callback}:voicemail/vm-return_call.wav"/>
+  	<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Forward}:voicemail/vm-to_forward.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="choose_greeting">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-choose_greeting_choose.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="choose_greeting_fail">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-choose_greeting_fail.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="record_greeting">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-record_greeting.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="record_message">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-record_message.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="greeting_selected">
+      <input pattern="^(\d+)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-greeting.wav"/>
+  	<action function="say" data="$1" method="pronounced" type="items"/>
+  	<action function="play-file" data="voicemail/vm-selected.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="play_greeting">
+      <input pattern="^(.*)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-person.wav"/>
+  	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
+  	<action function="play-file" data="voicemail/vm-not_available.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="say_number">
+      <input pattern="^(\d+)$">
+        <match>
+  	<action function="say" data="$1" method="pronounced" type="items"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="say_message_number">
+      <input>
+        <match>
+  	<action function="play-file" data="voicemail/vm-${VM-Message-Type}.wav"/> 
+  	<action function="play-file" data="voicemail/vm-message_number.wav"/>
+  	<action function="say" data="${VM-Message-Number}" method="pronounced" type="items"/> 
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="say_phone_number">
+      <input pattern="^(.*)$">
+        <match>
+  	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="say_name">
+      <input pattern="^(.*)$">
+        <match>
+  	<action function="say" data="$1" method="pronounced" type="name_spelled"/>
+        </match>
+      </input>
+    </macro>
+    <!-- Note: Update this to marked-urgent,emailed and saved once new sound files are recorded -->
+    <macro name="ack"> 
+      <input pattern="^(too-small)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-too-small.wav"/>
+        </match>
+      </input>
+      <input pattern="^(undeleted)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-message.wav"/>
+  	<action function="play-file" data="voicemail/vm-$1.wav"/>
+        </match>
+      </input>
+      <input pattern="^(deleted)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-message.wav"/>
+  	<action function="play-file" data="voicemail/vm-$1.wav"/>
+        </match>
+      </input>
+      <input pattern="^(saved)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-message.wav"/>
+  	<action function="play-file" data="voicemail/vm-$1.wav"/>
+        </match>
+      </input>
+      <input pattern="^(emailed)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-message.wav"/>
+  	<action function="play-file" data="voicemail/vm-$1.wav"/>
+        </match>
+      </input>
+      <input pattern="^(marked-urgent)$">
+        <match>
+  	<action function="play-file" data="voicemail/vm-message.wav"/>
+  	<action function="play-file" data="voicemail/vm-$1.wav"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="say_date">
+      <input pattern="^(.*)$">
+        <match>
+  	<action function="say" data="$1" method="pronounced" type="short_date_time"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="say_date_event">
+      <input>
+        <match>
+          <action function="say" data="${VM-Message-Received-Epoch}" method="pronounced" type="short_date_time"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="play_message">
+      <input>
+        <match>
+          <action function="play-file" data="${VM-Message-File-Path}"/>
+        </match>
+      </input>
+    </macro>
+  
+    <macro name="play_recording">
+      <input>
+        <match>
+          <action function="play-file" data="${VM-Record-File-Path}"/>
+        </match>
+      </input>
+    </macro>
+    
+    <macro name="disk_quota_exceeded">
+      <input>
+  	<match>
+  	    <action function="play-file" data="voicemail/vm-mailbox_full.wav"/>
+  	</match>
+      </input>
+    </macro>
+  </macros>
 </include><!--This line will be ignored it's here to validate the xml and is optional -->
diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c
index e58377ef5a..1ac0d38889 100644
--- a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c
+++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c
@@ -50,7 +50,8 @@ typedef enum {
 	XML_LDAP_CONFIG = 0,
 	XML_LDAP_DIRECTORY,
 	XML_LDAP_DIALPLAN,
-	XML_LDAP_PHRASE
+	XML_LDAP_PHRASE,
+	XML_LDAP_LANGUAGE
 } xml_ldap_query_type_t;
 
 SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load);
@@ -247,6 +248,8 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c
 		query_type = XML_LDAP_DIALPLAN;
 	} else if (!strcmp(section, "phrases")) {
 		query_type = XML_LDAP_PHRASE;
+	} else if (!strcmp(section, "languages")) {
+		query_type = XML_LDAP_LANGUAGE;
 	} else {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n");
 		return NULL;
@@ -269,6 +272,7 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c
 
 				case XML_LDAP_DIALPLAN:
 				case XML_LDAP_PHRASE:
+				case XML_LDAP_LANGUAGE:
 					break;
 				}
 			}
@@ -326,6 +330,7 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c
 				break;
 
 			case XML_LDAP_PHRASE:
+			case XML_LDAP_LANGUAGE:
 				break;
 			}
 		} else {
diff --git a/src/switch_ivr.c b/src/switch_ivr.c
index 07c341a580..825f2d30cd 100644
--- a/src/switch_ivr.c
+++ b/src/switch_ivr.c
@@ -29,6 +29,7 @@
  * Matt Klein <mklein@nmedia.net>
  * Michael Jerris <mike@jerris.com>
  * Ken Rice <krice at suspicious dot org>
+ * Marc Olivier Chouinard <mochouinard@moctel.com>
  *
  * switch_ivr.c -- IVR Library
  *
@@ -2327,9 +2328,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
 	switch_say_interface_t *si;
 	switch_channel_t *channel;
 	switch_status_t status = SWITCH_STATUS_FALSE;
-	const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *lname = NULL, *sound_path = NULL;
+	const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *sound_path = NULL;
 	switch_event_t *hint_data;
-	switch_xml_t cfg, xml = NULL, language, macros;
+	switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
 	char *p;
 
 	switch_assert(session);
@@ -2341,6 +2342,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
 	}
 
 	if (module_name) {
+		char *p;
 		p = switch_core_session_strdup(session, module_name);
 		module_name = p;
 		
@@ -2371,58 +2373,35 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
 	switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
 	switch_channel_event_set_data(channel, hint_data);
 
-	if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
+	if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
 		goto done;
 	}
 
-	if (!(macros = switch_xml_child(cfg, "macros"))) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
-		goto done;
-	}
-
-	if (!(language = switch_xml_child(macros, "language"))) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
-		goto done;
-	}
-
-	while (language) {
-		if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
-			const char *tmp;
-
-			if ((tmp = switch_xml_attr(language, "module"))) {
-				module_name = tmp;
-			}
-			break;
-		}
-		language = language->next;
-	}
-
-	if (!language) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
-		goto done;
-	}
-
-	if (!module_name) {
+	if ((p = (char *) switch_xml_attr(language, "say-module"))) {
+		module_name = switch_core_session_strdup(session, p);
+	} else if ((p = (char *) switch_xml_attr(language, "module"))) {
+		module_name = switch_core_session_strdup(session, p);
+		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
+	} else {
 		module_name = chan_lang;
 	}
 
-	if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
-		sound_path = (char *) switch_xml_attr(language, "sound_path");
+	if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
+		if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
+			sound_path = (char *) switch_xml_attr(language, "sound_path");
+		}
 	}
 
-	save_path = switch_channel_get_variable(channel, "sound_prefix");
-
-	if (sound_path) {
-		switch_channel_set_variable(channel, "sound_prefix", sound_path);
-		p = switch_core_session_strdup(session, sound_path);
-		sound_path = p;
+	if (channel) {
+		const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
+		if (!switch_true(p)) {
+			save_path = switch_channel_get_variable(channel, "sound_prefix");
+			if (sound_path) {
+				switch_channel_set_variable(channel, "sound_prefix", sound_path);
+			}
+		}
 	}
 
-	if (xml) {
-		switch_xml_free(xml);
-	}
-	
 	if ((si = switch_loadable_module_get_say_interface(module_name))) {
 		/* should go back and proto all the say mods to const.... */
 		switch_say_args_t say_args = {0};
@@ -2446,7 +2425,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
 	if (save_path) {
 		switch_channel_set_variable(channel, "sound_prefix", save_path);
 	}
-	
+
+	if (xml) {
+		switch_xml_free(xml);
+	}
+
 	return status;
 }
 
@@ -2463,9 +2446,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_string(switch_core_session_t *ses
 	switch_say_interface_t *si;
 	switch_channel_t *channel = NULL;
 	switch_status_t status = SWITCH_STATUS_FALSE;
-	const char *save_path = NULL, *chan_lang = NULL, *lname = NULL, *sound_path = NULL;
+	const char *save_path = NULL, *chan_lang = NULL, *sound_path = NULL;
 	switch_event_t *hint_data;
-	switch_xml_t cfg, xml = NULL, language, macros;
+	switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
 
 	if (session) {
 		channel = switch_core_session_get_channel(session);
@@ -2498,52 +2481,31 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_string(switch_core_session_t *ses
 		switch_channel_event_set_data(channel, hint_data);
 	}
 
-	if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
+	if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
 		goto done;
 	}
 
-	if (!(macros = switch_xml_child(cfg, "macros"))) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
-		goto done;
-	}
-
-	if (!(language = switch_xml_child(macros, "language"))) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
-		goto done;
-	}
-
-	while (language) {
-		if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
-			const char *tmp;
-
-			if ((tmp = switch_xml_attr(language, "module"))) {
-				module_name = tmp;
-			}
-			break;
-		}
-		language = language->next;
-	}
-
-	if (!language) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
-		goto done;
-	}
-
-	if (!module_name) {
+	if ((module_name = switch_xml_attr(language, "say-module"))) {
+	} else if ((module_name = switch_xml_attr(language, "module"))) {
+		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
+	} else {
 		module_name = chan_lang;
 	}
 
-	if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
-		sound_path = (char *) switch_xml_attr(language, "sound_path");
+	if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
+		if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
+			sound_path = (char *) switch_xml_attr(language, "sound_path");
+		}
 	}
 
 	if (channel) {
-		save_path = switch_channel_get_variable(channel, "sound_prefix");
-	}
-
-	if (sound_path && channel) {
-		switch_channel_set_variable(channel, "sound_prefix", sound_path);
+		const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");	
+		if (!switch_true(p)) {
+			save_path = switch_channel_get_variable(channel, "sound_prefix");
+			if (sound_path) {
+				switch_channel_set_variable(channel, "sound_prefix", sound_path);
+			}
+		}
 	}
 
 	if ((si = switch_loadable_module_get_say_interface(module_name))) {
diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c
index 6c769ecfd8..76cea5a666 100644
--- a/src/switch_ivr_play_say.c
+++ b/src/switch_ivr_play_say.c
@@ -28,6 +28,7 @@
  * Neal Horman <neal at wanlink dot com>
  * Matt Klein <mklein@nmedia.net>
  * Michael Jerris <mike@jerris.com>
+ * Marc Olivier Chouinard <mochouinard@moctel.com>
  *
  * switch_ivr_play_say.c -- IVR Library (functions to play or say audio)
  *
@@ -39,8 +40,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 														switch_input_args_t *args)
 {
 	switch_event_t *hint_data;
-	switch_xml_t cfg, xml = NULL, language, macros, macro, input, action;
-	char *lname = NULL, *mname = NULL;
+	switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL, macro, input, action;
 	switch_status_t status = SWITCH_STATUS_GENERR;
 	const char *old_sound_prefix = NULL, *sound_path = NULL, *tts_engine = NULL, *tts_voice = NULL;
 	const char *module_name = NULL, *chan_lang = NULL;
@@ -49,6 +49,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 	int matches = 0;
 	const char *pause_val;
 	int pause = 100;
+	const char *group_macro_name = NULL;
+	const char *local_macro_name = macro_name;
+	switch_bool_t sound_prefix_enforced = switch_true(switch_channel_get_variable(channel, "sound_prefix_enforced"));
+	switch_bool_t local_sound_prefix_enforced = SWITCH_FALSE;
 
 	if (!macro_name) {
 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No phrase macro specified.\n");
@@ -65,8 +69,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 		chan_lang = lang;
 	}
 
-	module_name = chan_lang;
-
 	switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS);
 	switch_assert(hint_data);
 
@@ -82,40 +84,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 	}
 	switch_channel_event_set_data(channel, hint_data);
 
-	if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
+	if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
 		goto done;
 	}
 
-	if (!(macros = switch_xml_child(cfg, "macros"))) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
-		goto done;
+	if ((module_name = switch_xml_attr(language, "say-module"))) {
+	} else if ((module_name = switch_xml_attr(language, "module"))) {
+		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute. Use say-module instead\n");
+	} else {
+		module_name = chan_lang;
 	}
 
-	if (!(language = switch_xml_child(macros, "language"))) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
-		goto done;
-	}
-
-	while (language) {
-		if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
-			const char *tmp;
-
-			if ((tmp = switch_xml_attr(language, "module"))) {
-				module_name = tmp;
-			}
-			break;
+	if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
+		if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
+			sound_path = (char *) switch_xml_attr(language, "sound_path");
 		}
-		language = language->next;
-	}
-
-	if (!language) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
-		goto done;
-	}
-
-	if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
-		sound_path = (char *) switch_xml_attr(language, "sound_path");
 	}
 
 	if (!(tts_engine = (char *) switch_xml_attr(language, "tts-engine"))) {
@@ -126,7 +109,41 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 		tts_voice = (char *) switch_xml_attr(language, "tts_voice");
 	}
 
-	if (sound_path) {
+	/* If we use the new structure, check for a group name */
+	if (language != macros) {
+		char *p;
+		char *macro_name_dup = switch_core_session_strdup(session, macro_name);
+		const char *group_sound_path;
+		const char *sound_prefix_enforced_str;
+
+		if ((p = strchr(macro_name_dup, '@'))) {
+			*p++ = '\0';
+			local_macro_name = macro_name_dup;
+			group_macro_name = p;
+
+			if (!(macros = switch_xml_find_child(phrases, "macros", "name", group_macro_name))) {
+				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros group %s.\n", group_macro_name);
+				goto done;
+			}
+		}
+		/* Support override of certain language attribute */
+		if ((group_sound_path = (char *) switch_xml_attr(macros, "sound-prefix")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound-path")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound_path"))) {
+			sound_path = group_sound_path;
+		}
+
+		if (sound_prefix_enforced == SWITCH_FALSE && (sound_prefix_enforced_str = switch_xml_attr(macros, "sound-prefix-enforced"))
+				&& (local_sound_prefix_enforced = switch_true(sound_prefix_enforced_str)) == SWITCH_TRUE) {
+			switch_channel_set_variable(channel, "sound_prefix_enforced", sound_prefix_enforced_str);
+		}
+
+	}
+
+	if (!(macro = switch_xml_find_child(macros, "macro", "name", local_macro_name))) {
+		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name);
+		goto done;
+	}
+
+	if (sound_path && sound_prefix_enforced == SWITCH_FALSE) {
 		char *p;
 		old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix"));
 		p = switch_core_session_strdup(session, old_sound_prefix);
@@ -134,23 +151,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 		switch_channel_set_variable(channel, "sound_prefix", sound_path);
 	}
 
-	if (!(macro = switch_xml_child(language, "macro"))) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find any macro tags.\n");
-		goto done;
-	}
-
-	while (macro) {
-		if ((mname = (char *) switch_xml_attr(macro, "name")) && !strcasecmp(mname, macro_name)) {
-			break;
-		}
-		macro = macro->next;
-	}
-
-	if (!macro) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name);
-		goto done;
-	}
-
 	if ((pause_val = switch_xml_attr(macro, "pause"))) {
 		int tmp = atoi(pause_val);
 		if (tmp >= 0) {
@@ -342,6 +342,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 	if (old_sound_prefix) {
 		switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix);
 	}
+	if (local_sound_prefix_enforced == SWITCH_TRUE) {
+		switch_channel_set_variable(channel, "sound_prefix_enforced", NULL);
+	}
+
 	if (xml) {
 		switch_xml_free(xml);
 	}
diff --git a/src/switch_xml.c b/src/switch_xml.c
index 00f6ddd48e..0ad8768cad 100644
--- a/src/switch_xml.c
+++ b/src/switch_xml.c
@@ -25,7 +25,7 @@
  * 
  * Anthony Minessale II <anthm@freeswitch.org>
  * Simon Capper <skyjunky@sbcglobal.net>
- *
+ * Marc Olivier Chouinard <mochouinard@moctel.com>
  *
  * switch_xml.c -- XML PARSER
  *
@@ -2785,6 +2785,62 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) {
 	return time_match;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language) {
+	switch_status_t status = SWITCH_STATUS_FALSE;
+
+	if (switch_xml_locate("languages", NULL, NULL, NULL, root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
+		switch_xml_t sub_macros;
+
+		if (switch_xml_locate("phrases", NULL, NULL, NULL, root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of languages and phrases failed.\n");
+			goto done;
+		}
+		if (!(sub_macros = switch_xml_child(*node, "macros"))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find macros tag.\n");
+			switch_xml_free(*root);
+			*root = NULL;
+			*node = NULL;
+			goto done;
+		}
+		if (!(*language = switch_xml_find_child(sub_macros, "language", "name", str_language))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language);
+			switch_xml_free(*root);
+			*root = NULL;
+			*node = NULL;
+			goto done;
+		}
+		*macros = *language;
+	} else {
+		if (!(*language = switch_xml_find_child(*node, "language", "name", str_language))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language);
+			switch_xml_free(*root);
+			*root = NULL;
+			goto done;
+		}
+		if (!(*phrases = switch_xml_child(*language, "phrases"))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find phrases tag.\n");
+			switch_xml_free(*root);
+			*root = NULL;
+			*node = NULL;
+			*language = NULL;
+			goto done;
+		}
+
+		if (!(*macros = switch_xml_child(*phrases, "macros"))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find macros tag.\n");
+			switch_xml_free(*root);
+			*root = NULL;
+			*node = NULL;
+			*language = NULL;
+			*phrases = NULL;
+			goto done;
+		}
+	}
+	status = SWITCH_STATUS_SUCCESS;
+
+done:
+	return status;
+}
 
 #ifdef WIN32
 /*