Index: boost/locale/generator.hpp
===================================================================
--- boost/locale/generator.hpp	(revision 80147)
+++ boost/locale/generator.hpp	(working copy)
@@ -136,6 +136,27 @@
             void clear_domains();
 
             ///
+            /// Adds a new format for use when finding Gettext catalogs.
+            ///
+            /// Formats are the same syntax as the Boost format functions, but
+            /// use the following variables:
+            ///
+            /// \li {1} A path to search for catalogs in.
+            /// \li {2} The locale's name.
+            /// \li {3} The locale's category.
+            /// \li {4} The Gettext domain.
+            ///
+            /// For example, \c {1}/{2}/{3}/{4}.mo is the standard Gettext layout.
+            /// Using something like \c {1}/{2}.mo would compact the folder hierarchy.
+            ///
+            void add_path_format(std::string const &path);
+
+            ///
+            /// Remove all added formats from the list
+            ///
+            void clear_path_formats();
+
+            ///
             /// Add a search path where dictionaries are looked in.
             ///
             /// \note
Index: boost/locale/gnu_gettext.hpp
===================================================================
--- boost/locale/gnu_gettext.hpp	(revision 80147)
+++ boost/locale/gnu_gettext.hpp	(working copy)
@@ -132,24 +132,25 @@
     ///
 
     template<typename CharType>
-    message_format<CharType> *create_messages_facet(messages_info const &info);
+    message_format<CharType> *create_messages_facet(messages_info const &info,
+        std::vector<std::string> const &path_formats = std::vector<std::string>());
 
     /// \cond INTERNAL
     
     template<>
-    BOOST_LOCALE_DECL message_format<char> *create_messages_facet(messages_info const &info);
+    BOOST_LOCALE_DECL message_format<char> *create_messages_facet(messages_info const &info, std::vector<std::string> const &path_formats);
     
     template<>
-    BOOST_LOCALE_DECL message_format<wchar_t> *create_messages_facet(messages_info const &info);
+    BOOST_LOCALE_DECL message_format<wchar_t> *create_messages_facet(messages_info const &info, std::vector<std::string> const &path_formats);
 
     #ifdef BOOST_HAS_CHAR16_T
     template<>
-    BOOST_LOCALE_DECL message_format<char16_t> *create_messages_facet(messages_info const &info);
+    BOOST_LOCALE_DECL message_format<char16_t> *create_messages_facet(messages_info const &info, std::vector<std::string> const &path_formats);
     #endif
     
     #ifdef BOOST_HAS_CHAR32_T
     template<>
-    BOOST_LOCALE_DECL message_format<char32_t> *create_messages_facet(messages_info const &info);
+    BOOST_LOCALE_DECL message_format<char32_t> *create_messages_facet(messages_info const &info, std::vector<std::string> const &path_formats);
     #endif
 
     /// \endcond
Index: libs/locale/doc/messages_formatting.txt
===================================================================
--- libs/locale/doc/messages_formatting.txt	(revision 80147)
+++ libs/locale/doc/messages_formatting.txt	(working copy)
@@ -111,6 +111,9 @@
     // Specify location of dictionaries
     gen.add_messages_path(".");
     gen.add_messages_domain("hello");
+    
+    // Use a path format like "./en_US/LC_MESSAGES/hello.mo"
+    gen.add_path_format("{1}/{2}/{3}/{4}.mo");
 
     // Generate locales and imbue them to iostream
     locale::global(gen(""));
Index: libs/locale/src/icu/icu_backend.cpp
===================================================================
--- libs/locale/src/icu/icu_backend.cpp	(revision 80147)
+++ libs/locale/src/icu/icu_backend.cpp	(working copy)
@@ -31,6 +31,7 @@
         icu_localization_backend(icu_localization_backend const &other) : 
             localization_backend(),
             paths_(other.paths_),
+            path_formats_(other.path_formats_),
             domains_(other.domains_),
             locale_id_(other.locale_id_),
             invalid_(true),
@@ -49,6 +50,8 @@
                 locale_id_ = value;
             else if(name=="message_path")
                 paths_.push_back(value);
+            else if(name=="message_path_format")
+                path_formats_.push_back(value);
             else if(name=="message_application")
                 domains_.push_back(value);
             else if(name=="use_ansi_encoding")
@@ -62,6 +65,7 @@
             locale_id_.clear();
             paths_.clear();
             domains_.clear();
+            path_formats_.clear();
         }
 
         void prepare_data()
@@ -114,16 +118,16 @@
                     minf.paths = paths_;
                     switch(type) {
                     case char_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char>(minf, path_formats_));
                     case wchar_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf, path_formats_));
                     #ifdef BOOST_HAS_CHAR16_T
                     case char16_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf, path_formats_));
                     #endif
                     #ifdef BOOST_HAS_CHAR32_T
                     case char32_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf, path_formats_));
                     #endif
                     default:
                         return base;
@@ -143,6 +147,7 @@
     private:
 
         std::vector<std::string> paths_;
+        std::vector<std::string> path_formats_;
         std::vector<std::string> domains_;
         std::string locale_id_;
 
Index: libs/locale/src/posix/posix_backend.cpp
===================================================================
--- libs/locale/src/posix/posix_backend.cpp	(revision 80147)
+++ libs/locale/src/posix/posix_backend.cpp	(working copy)
@@ -33,6 +33,7 @@
         posix_localization_backend(posix_localization_backend const &other) : 
             localization_backend(),
             paths_(other.paths_),
+            path_formats_(other.path_formats_),
             domains_(other.domains_),
             locale_id_(other.locale_id_),
             invalid_(true)
@@ -50,6 +51,8 @@
                 locale_id_ = value;
             else if(name=="message_path")
                 paths_.push_back(value);
+            else if(name=="message_path_format")
+                path_formats_.push_back(value);
             else if(name=="message_application")
                 domains_.push_back(value);
 
@@ -59,6 +62,7 @@
             invalid_ = true;
             locale_id_.clear();
             paths_.clear();
+            path_formats_.clear();
             domains_.clear();
         }
 
@@ -137,16 +141,16 @@
                     minf.paths = paths_;
                     switch(type) {
                     case char_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char>(minf, path_formats_));
                     case wchar_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf, path_formats_));
                     #ifdef BOOST_HAS_CHAR16_T
                     case char16_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf, path_formats_));
                     #endif
                     #ifdef BOOST_HAS_CHAR32_T
                     case char32_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf, path_formats_));
                     #endif
                     default:
                         return base;
@@ -162,6 +166,7 @@
     private:
 
         std::vector<std::string> paths_;
+        std::vector<std::string> path_formats_;
         std::vector<std::string> domains_;
         std::string locale_id_;
         std::string real_id_;
Index: libs/locale/src/shared/generator.cpp
===================================================================
--- libs/locale/src/shared/generator.cpp	(revision 80147)
+++ libs/locale/src/shared/generator.cpp	(working copy)
@@ -38,6 +38,7 @@
             bool use_ansi_encoding;
 
             std::vector<std::string> paths;
+            std::vector<std::string> path_formats;
             std::vector<std::string> domains;
 
             std::map<std::string,std::vector<std::string> > options;
@@ -96,6 +97,17 @@
         {
             d->domains.clear();
         }
+
+        void generator::add_path_format(std::string const &format)
+        {
+            if(std::find(d->path_formats.begin(),d->path_formats.end(),format) == d->path_formats.end())
+                d->path_formats.push_back(format);
+        }
+
+        void generator::clear_path_formats()
+        {
+            d->path_formats.clear();
+        }
         void generator::add_messages_path(std::string const &path)
         {
             d->paths.push_back(path);
@@ -184,6 +196,8 @@
                 backend->set_option("message_application",d->domains[i]);
             for(size_t i=0;i<d->paths.size();i++)
                 backend->set_option("message_path",d->paths[i]);
+            for(size_t i=0;i<d->path_formats.size();i++)
+                backend->set_option("message_path_format",d->path_formats[i]);
         }
         
     } // locale
Index: libs/locale/src/shared/message.cpp
===================================================================
--- libs/locale/src/shared/message.cpp	(revision 80147)
+++ libs/locale/src/shared/message.cpp	(working copy)
@@ -9,6 +9,7 @@
 #include <boost/config.hpp>
 #include <boost/locale/message.hpp>
 #include <boost/locale/gnu_gettext.hpp>
+#include <boost/locale/format.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/locale/encoding.hpp>
 #ifdef BOOST_MSVC
@@ -533,7 +534,7 @@
                     return p->second;
                 }
 
-                mo_message(messages_info const &inf)
+                mo_message(messages_info const &inf, std::vector<std::string> const &path_formats)
                 {
                     std::string language = inf.language;
                     std::string variant = inf.variant;
@@ -543,6 +544,11 @@
                     std::vector<messages_info::domain> const &domains = inf.domains;
                     std::vector<std::string> const &search_paths = inf.paths;
                     
+                    std::vector<std::string> formats = path_formats;
+                    
+                    if(formats.empty())
+                        formats.push_back("{1}/{2}/{3}/{4}.mo");
+                    
                     //
                     // List of fallbacks: en_US@euro, en@euro, en_US, en. 
                     //
@@ -574,8 +580,10 @@
                         bool found=false; 
                         for(unsigned j=0;!found && j<paths.size();j++) {
                             for(unsigned i=0;!found && i<search_paths.size();i++) {
-                                std::string full_path = search_paths[i]+"/"+paths[j]+"/" + lc_cat + "/"+domain+".mo";
-                                found = load_file(full_path,encoding,key_encoding,id,inf.callback);
+                                for(unsigned k=0;!found && k<formats.size();k++) {
+                                    std::string full_path = (format(formats[k]) % search_paths[i] % paths[j] % lc_cat % domain).str(std::locale::classic());
+                                    found = load_file(full_path,encoding,key_encoding,id,inf.callback);
+                                }
                             }
                         }
                     }
@@ -744,23 +752,23 @@
             };
 
             template<>
-            message_format<char> *create_messages_facet(messages_info const &info)
+            message_format<char> *create_messages_facet(messages_info const &info, std::vector<std::string> const &path_formats)
             {
-                return new mo_message<char>(info);
+                return new mo_message<char>(info, path_formats);
             }
 
             template<>
-            message_format<wchar_t> *create_messages_facet(messages_info const &info)
+            message_format<wchar_t> *create_messages_facet(messages_info const &info, std::vector<std::string> const &path_formats)
             {
-                return new mo_message<wchar_t>(info);
+                return new mo_message<wchar_t>(info, path_formats);
             }
             
             #ifdef BOOST_HAS_CHAR16_T
 
             template<>
-            message_format<char16_t> *create_messages_facet(messages_info const &info)
+            message_format<char16_t> *create_messages_facet(messages_info const &info, std::vector<std::string> const &path_formats)
             {
-                return new mo_message<char16_t>(info);
+                return new mo_message<char16_t>(info, path_formats);
             }
             #endif
             
@@ -769,7 +777,7 @@
             template<>
             message_format<char32_t> *create_messages_facet(messages_info const &info)
             {
-                return new mo_message<char32_t>(info);
+                return new mo_message<char32_t>(info, path_formats);
             }
             #endif
 
Index: libs/locale/src/std/std_backend.cpp
===================================================================
--- libs/locale/src/std/std_backend.cpp	(revision 80147)
+++ libs/locale/src/std/std_backend.cpp	(working copy)
@@ -40,6 +40,7 @@
         std_localization_backend(std_localization_backend const &other) : 
             localization_backend(),
             paths_(other.paths_),
+            path_formats_(other.path_formats_),
             domains_(other.domains_),
             locale_id_(other.locale_id_),
             invalid_(true),
@@ -58,6 +59,8 @@
                 locale_id_ = value;
             else if(name=="message_path")
                 paths_.push_back(value);
+            else if(name=="message_path_format")
+                path_formats_.push_back(value);
             else if(name=="message_application")
                 domains_.push_back(value);
             else if(name=="use_ansi_encoding")
@@ -70,6 +73,7 @@
             use_ansi_encoding_ = false;
             locale_id_.clear();
             paths_.clear();
+            path_formats_.clear();
             domains_.clear();
         }
 
@@ -187,16 +191,16 @@
                     minf.paths = paths_;
                     switch(type) {
                     case char_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char>(minf, path_formats_));
                     case wchar_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf, path_formats_));
                     #ifdef BOOST_HAS_CHAR16_T
                     case char16_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf, path_formats_));
                     #endif
                     #ifdef BOOST_HAS_CHAR32_T
                     case char32_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf, path_formats_));
                     #endif
                     default:
                         return base;
@@ -212,6 +216,7 @@
     private:
 
         std::vector<std::string> paths_;
+        std::vector<std::string> path_formats_;
         std::vector<std::string> domains_;
         std::string locale_id_;
 
Index: libs/locale/src/win32/win_backend.cpp
===================================================================
--- libs/locale/src/win32/win_backend.cpp	(revision 80147)
+++ libs/locale/src/win32/win_backend.cpp	(working copy)
@@ -31,6 +31,7 @@
         winapi_localization_backend(winapi_localization_backend const &other) :
             localization_backend(), 
             paths_(other.paths_),
+            path_formats_(other.path_formats_),
             domains_(other.domains_),
             locale_id_(other.locale_id_),
             invalid_(true)
@@ -48,6 +49,8 @@
                 locale_id_ = value;
             else if(name=="message_path")
                 paths_.push_back(value);
+            else if(name=="message_path_format")
+                path_formats_.push_back(value);
             else if(name=="message_application")
                 domains_.push_back(value);
 
@@ -57,6 +60,7 @@
             invalid_ = true;
             locale_id_.clear();
             paths_.clear();
+            path_formats_.clear();
             domains_.clear();
         }
 
@@ -115,9 +119,9 @@
                     minf.paths = paths_;
                     switch(type) {
                     case char_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<char>(minf, path_formats_));
                     case wchar_t_facet:
-                        return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
+                        return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf, path_formats_));
                     default:
                         return base;
                     }
@@ -134,6 +138,7 @@
     private:
 
         std::vector<std::string> paths_;
+        std::vector<std::string> path_formats_;
         std::vector<std::string> domains_;
         std::string locale_id_;
         std::string real_id_;
Index: libs/locale/test/test_message.cpp
===================================================================
--- libs/locale/test/test_message.cpp	(revision 80147)
+++ libs/locale/test/test_message.cpp	(working copy)
@@ -344,7 +344,7 @@
                 g.add_messages_path(argv[1]);
             else
                 g.add_messages_path("./");
-
+            g.add_path_format("{1}/{2}/{3}/{4}.mo");
             
             std::string locales[] = { "he_IL.UTF-8", "he_IL.ISO8859-8" };
 
@@ -442,8 +442,10 @@
                 info.paths.push_back(argv[1]);
             else
                 info.paths.push_back("./");
+            // The Gettext path format should be added by default.
 
             info.domains.push_back(bl::gnu_gettext::messages_info::domain("default"));
+
             info.callback = file_loader();
 
             std::locale l(std::locale::classic(),boost::locale::gnu_gettext::create_messages_facet<char>(info));
@@ -465,7 +467,8 @@
                     g.add_messages_path(argv[1]);
                 else
                     g.add_messages_path("./");
-                
+                g.add_path_format("{1}/{2}/{3}/{4}.mo");
+
                 std::locale l = g("he_IL.UTF-8");
 
                 // narrow
@@ -494,6 +497,8 @@
                 else
                     g.add_messages_path("./");
                 
+                g.add_path_format("{1}/{2}/{3}/{4}.mo");
+
                 std::locale l = g("he_IL.UTF-8");
 
                 // narrow non-UTF-8 keys
