diff --git a/include/boost/property_tree/detail/exception_implementation.hpp b/include/boost/property_tree/detail/exception_implementation.hpp
new file mode 100644
index 0000000..bb39135
--- /dev/null
+++ b/include/boost/property_tree/detail/exception_implementation.hpp
@@ -0,0 +1,83 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
+
+namespace boost { namespace property_tree
+{
+
+    namespace detail
+    {
+
+        // Helper for preparing what string in ptree_bad_path exception
+        template<class P> inline
+        std::string prepare_bad_path_what(const std::string &what,
+                                          const P &path)
+        {
+            return what + " (" + path.dump() + ")";
+        }
+
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // ptree_error
+
+    inline ptree_error::ptree_error(const std::string &w): 
+        std::runtime_error(w) 
+    {
+    }
+
+    inline ptree_error::~ptree_error() throw()
+    {
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // ptree_bad_data
+
+    template<class D> inline
+    ptree_bad_data::ptree_bad_data(const std::string &w, const D &d):
+        ptree_error(w), m_data(d)
+    {
+    }
+
+    inline ptree_bad_data::~ptree_bad_data() throw()
+    {
+    }
+
+    template<class D> inline
+    D ptree_bad_data::data() const
+    {
+        return boost::any_cast<D>(m_data);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // ptree_bad_path
+
+    template<class P> inline
+    ptree_bad_path::ptree_bad_path(const std::string &w, const P &p):
+        ptree_error(detail::prepare_bad_path_what(w, p)), m_path(p)
+    {
+
+    }
+
+    inline ptree_bad_path::~ptree_bad_path() throw()
+    {
+    }
+
+    template<class P> inline
+    P ptree_bad_path::path() const
+    {
+        return boost::any_cast<P>(m_path);
+    }
+
+}}
+
+#endif
diff --git a/include/boost/property_tree/detail/file_parser_error.hpp b/include/boost/property_tree/detail/file_parser_error.hpp
new file mode 100644
index 0000000..ff90583
--- /dev/null
+++ b/include/boost/property_tree/detail/file_parser_error.hpp
@@ -0,0 +1,88 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+#include <string>
+
+namespace boost { namespace property_tree
+{
+
+    //! File parse error
+    class file_parser_error: public ptree_error
+    {
+
+    public:
+
+        ///////////////////////////////////////////////////////////////////////
+        // Construction & destruction
+
+        // Construct error
+        file_parser_error(const std::string &msg,
+                          const std::string &file,
+                          unsigned long l) :
+            ptree_error(format_what(msg, file, l)),
+            m_message(msg), m_filename(file), m_line(l)
+        {
+        }
+
+        ~file_parser_error() throw()
+            // gcc 3.4.2 complains about lack of throw specifier on compiler
+            // generated dtor
+        {
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        // Data access
+
+        // Get error message (without line and file - use what() to get
+        // full message)
+        std::string message() const
+        {
+            return m_message;
+        }
+
+        // Get error filename
+        std::string filename() const
+        {
+            return m_filename;
+        }
+
+        // Get error line number
+        unsigned long line() const
+        {
+            return m_line;
+        }
+
+    private:
+
+        std::string m_message;
+        std::string m_filename;
+        unsigned long m_line;
+
+        // Format error message to be returned by std::runtime_error::what()
+        static std::string format_what(const std::string &msg,
+                                       const std::string &file,
+                                       unsigned long l)
+        {
+            std::stringstream stream;
+            stream << (file.empty() ? "<unspecified file>" : file.c_str());
+            if (l > 0)
+                stream << '(' << l << ')';
+            stream << ": " << msg;
+            return stream.str();
+        }
+
+    };
+
+} }
+
+#endif
diff --git a/include/boost/property_tree/detail/info_parser_error.hpp b/include/boost/property_tree/detail/info_parser_error.hpp
new file mode 100644
index 0000000..e7f06a1
--- /dev/null
+++ b/include/boost/property_tree/detail/info_parser_error.hpp
@@ -0,0 +1,32 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED
+
+#include <boost/property_tree/detail/file_parser_error.hpp>
+#include <string>
+
+namespace boost { namespace property_tree { namespace info_parser
+{
+
+    class info_parser_error: public file_parser_error
+    {
+    public:
+        info_parser_error(const std::string &message,
+                          const std::string &filename,
+                          unsigned long line) :
+            file_parser_error(message, filename, line)
+        {
+        }
+    };
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/info_parser_read.hpp b/include/boost/property_tree/detail/info_parser_read.hpp
new file mode 100644
index 0000000..87ef2cd
--- /dev/null
+++ b/include/boost/property_tree/detail/info_parser_read.hpp
@@ -0,0 +1,391 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_READ_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_READ_HPP_INCLUDED
+
+#include "boost/property_tree/ptree.hpp"
+#include "boost/property_tree/detail/info_parser_error.hpp"
+#include "boost/property_tree/detail/info_parser_utils.hpp"
+#include <iterator>
+#include <string>
+#include <stack>
+#include <fstream>
+#include <cctype>
+
+namespace boost { namespace property_tree { namespace info_parser
+{
+
+    // Expand known escape sequences
+    template<class It>
+    std::basic_string<typename std::iterator_traits<It>::value_type>
+        expand_escapes(It b, It e)
+    {
+        typedef typename std::iterator_traits<It>::value_type Ch;
+        std::basic_string<Ch> result;
+        while (b != e)
+        {
+            if (*b == Ch('\\'))
+            {
+                ++b;
+                if (b == e)
+                {
+                    BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                        "character expected after backslash", "", 0));
+                }
+                else if (*b == Ch('0')) result += Ch('\0');
+                else if (*b == Ch('a')) result += Ch('\a');
+                else if (*b == Ch('b')) result += Ch('\b');
+                else if (*b == Ch('f')) result += Ch('\f');
+                else if (*b == Ch('n')) result += Ch('\n');
+                else if (*b == Ch('r')) result += Ch('\r');
+                else if (*b == Ch('t')) result += Ch('\t');
+                else if (*b == Ch('v')) result += Ch('\v');
+                else if (*b == Ch('"')) result += Ch('"');
+                else if (*b == Ch('\'')) result += Ch('\'');
+                else if (*b == Ch('\\')) result += Ch('\\');
+                else
+                    BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                        "unknown escape sequence", "", 0));
+            }
+            else
+                result += *b;
+            ++b;
+        }
+        return result;
+    }
+    
+    // Detect whitespace in a not very smart way.
+    template <class Ch>
+    bool is_ascii_space(Ch c)
+    {
+        // Everything outside ASCII is not space.
+        unsigned n = c;
+        if (n > 127)
+            return false;
+        return std::isspace(c) != 0;
+    }
+
+    // Advance pointer past whitespace
+    template<class Ch>
+    void skip_whitespace(const Ch *&text)
+    {
+        using namespace std;
+        while (is_ascii_space(*text))
+            ++text;
+    }
+
+    // Extract word (whitespace delimited) and advance pointer accordingly
+    template<class Ch>
+    std::basic_string<Ch> read_word(const Ch *&text)
+    {
+        using namespace std;
+        skip_whitespace(text);
+        const Ch *start = text;
+        while (!is_ascii_space(*text) && *text != Ch(';') && *text != Ch('\0'))
+            ++text;
+        return expand_escapes(start, text);
+    }
+
+    // Extract line (eol delimited) and advance pointer accordingly
+    template<class Ch>
+    std::basic_string<Ch> read_line(const Ch *&text)
+    {
+        using namespace std;
+        skip_whitespace(text);
+        const Ch *start = text;
+        while (*text != Ch('\0') && *text != Ch(';'))
+            ++text;
+        while (text > start && is_ascii_space(*(text - 1)))
+            --text;
+        return expand_escapes(start, text);
+    }
+
+    // Extract string (inside ""), and advance pointer accordingly
+    // Set need_more_lines to true if \ continuator found
+    template<class Ch>
+    std::basic_string<Ch> read_string(const Ch *&text, bool *need_more_lines)
+    {
+        skip_whitespace(text);
+        if (*text == Ch('\"'))
+        {
+
+            // Skip "
+            ++text;
+
+            // Find end of string, but skip escaped "
+            bool escaped = false;
+            const Ch *start = text;
+            while ((escaped || *text != Ch('\"')) && *text != Ch('\0'))
+            {
+                escaped = (!escaped && *text == Ch('\\'));
+                ++text;
+            }
+
+            // If end of string found
+            if (*text == Ch('\"'))
+            {
+                std::basic_string<Ch> result = expand_escapes(start, text++);
+                skip_whitespace(text);
+                if (*text == Ch('\\'))
+                {
+                    if (!need_more_lines)
+                        BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                            "unexpected \\", "", 0));
+                    ++text;
+                    skip_whitespace(text);
+                    if (*text == Ch('\0') || *text == Ch(';'))
+                        *need_more_lines = true;
+                    else
+                        BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                            "expected end of line after \\", "", 0));
+                }
+                else
+                    if (need_more_lines)
+                        *need_more_lines = false;
+                return result;
+            }
+            else
+                BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                    "unexpected end of line", "", 0));
+
+        }
+        else
+            BOOST_PROPERTY_TREE_THROW(info_parser_error("expected \"", "", 0));
+    }
+
+    // Extract key
+    template<class Ch>
+    std::basic_string<Ch> read_key(const Ch *&text)
+    {
+        skip_whitespace(text);
+        if (*text == Ch('\"'))
+            return read_string(text, NULL);
+        else
+            return read_word(text);
+    }
+
+    // Extract data
+    template<class Ch>
+    std::basic_string<Ch> read_data(const Ch *&text, bool *need_more_lines)
+    {
+        skip_whitespace(text);
+        if (*text == Ch('\"'))
+            return read_string(text, need_more_lines);
+        else
+        {
+            *need_more_lines = false;
+            return read_word(text);
+        }
+    }
+
+    // Build ptree from info stream
+    template<class Ptree, class Ch>
+    void read_info_internal(std::basic_istream<Ch> &stream,
+                            Ptree &pt,
+                            const std::string &filename,
+                            int include_depth)
+    {
+        typedef std::basic_string<Ch> str_t;
+        // Possible parser states
+        enum state_t {
+            s_key,              // Parser expects key
+            s_data,             // Parser expects data
+            s_data_cont         // Parser expects data continuation
+        };
+
+        unsigned long line_no = 0;
+        state_t state = s_key;          // Parser state
+        Ptree *last = NULL;             // Pointer to last created ptree
+        // Define line here to minimize reallocations
+        str_t line;
+
+        // Initialize ptree stack (used to handle nesting)
+        std::stack<Ptree *> stack;
+        stack.push(&pt);                // Push root ptree on stack initially
+
+        try {
+            // While there are characters in the stream
+            while (stream.good()) {
+                // Read one line from stream
+                ++line_no;
+                std::getline(stream, line);
+                if (!stream.good() && !stream.eof())
+                    BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                        "read error", filename, line_no));
+                const Ch *text = line.c_str();
+
+                // If directive found
+                skip_whitespace(text);
+                if (*text == Ch('#')) {
+                    // Determine directive type
+                    ++text;     // skip #
+                    std::basic_string<Ch> directive = read_word(text);
+                    if (directive == convert_chtype<Ch, char>("include")) {
+                        // #include
+                        if (include_depth > 100) {
+                            BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                                "include depth too large, "
+                                "probably recursive include",
+                                filename, line_no));
+                        }
+                        str_t s = read_string(text, NULL);
+                        std::string inc_name =
+                            convert_chtype<char, Ch>(s.c_str());
+                        std::basic_ifstream<Ch> inc_stream(inc_name.c_str());
+                        if (!inc_stream.good())
+                            BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                                "cannot open include file " + inc_name,
+                                filename, line_no));
+                        read_info_internal(inc_stream, *stack.top(),
+                                           inc_name, include_depth + 1);
+                    } else {   // Unknown directive
+                        BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                            "unknown directive", filename, line_no));
+                    }
+
+                    // Directive must be followed by end of line
+                    skip_whitespace(text);
+                    if (*text != Ch('\0')) {
+                        BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                            "expected end of line", filename, line_no));
+                    }
+
+                    // Go to next line
+                    continue;
+                }
+
+                // While there are characters left in line
+                while (1) {
+
+                    // Stop parsing on end of line or comment
+                    skip_whitespace(text);
+                    if (*text == Ch('\0') || *text == Ch(';')) {
+                        if (state == s_data)    // If there was no data set state to s_key
+                            state = s_key;
+                        break;
+                    }
+
+                    // Process according to current parser state
+                    switch (state)
+                    {
+
+                        // Parser expects key
+                        case s_key:
+                        {
+
+                            if (*text == Ch('{'))   // Brace opening found
+                            {
+                                if (!last)
+                                    BOOST_PROPERTY_TREE_THROW(info_parser_error("unexpected {", "", 0));
+                                stack.push(last);
+                                last = NULL;
+                                ++text;
+                            }
+                            else if (*text == Ch('}'))  // Brace closing found
+                            {
+                                if (stack.size() <= 1)
+                                    BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched }", "", 0));
+                                stack.pop();
+                                last = NULL;
+                                ++text;
+                            }
+                            else    // Key text found
+                            {
+                                std::basic_string<Ch> key = read_key(text);
+                                last = &stack.top()->push_back(
+                                    std::make_pair(key, Ptree()))->second;
+                                state = s_data;
+                            }
+
+                        }; break;
+
+                        // Parser expects data
+                        case s_data:
+                        {
+                            
+                            // Last ptree must be defined because we are going to add data to it
+                            BOOST_ASSERT(last);
+                            
+                            if (*text == Ch('{'))   // Brace opening found
+                            {
+                                stack.push(last);
+                                last = NULL;
+                                ++text;
+                                state = s_key;
+                            }
+                            else if (*text == Ch('}'))  // Brace closing found
+                            {
+                                if (stack.size() <= 1)
+                                    BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched }", "", 0));
+                                stack.pop();
+                                last = NULL;
+                                ++text;
+                                state = s_key;
+                            }
+                            else    // Data text found
+                            {
+                                bool need_more_lines;
+                                std::basic_string<Ch> data = read_data(text, &need_more_lines);
+                                last->data() = data;
+                                state = need_more_lines ? s_data_cont : s_key;
+                            }
+
+
+                        }; break;
+
+                        // Parser expects continuation of data after \ on previous line
+                        case s_data_cont:
+                        {
+                            
+                            // Last ptree must be defined because we are going to update its data
+                            BOOST_ASSERT(last);
+                            
+                            if (*text == Ch('\"'))  // Continuation must start with "
+                            {
+                                bool need_more_lines;
+                                std::basic_string<Ch> data = read_string(text, &need_more_lines);
+                                last->put_value(last->template get_value<std::basic_string<Ch> >() + data);
+                                state = need_more_lines ? s_data_cont : s_key;
+                            }
+                            else
+                                BOOST_PROPERTY_TREE_THROW(info_parser_error("expected \" after \\ in previous line", "", 0));
+
+                        }; break;
+
+                        // Should never happen
+                        default:
+                            BOOST_ASSERT(0);
+
+                    }
+                }
+            }
+
+            // Check if stack has initial size, otherwise some {'s have not been closed
+            if (stack.size() != 1)
+                BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched {", "", 0));
+
+        }
+        catch (info_parser_error &e)
+        {
+            // If line undefined rethrow error with correct filename and line
+            if (e.line() == 0)
+            {
+                BOOST_PROPERTY_TREE_THROW(info_parser_error(e.message(), filename, line_no));
+            }
+            else
+                BOOST_PROPERTY_TREE_THROW(e);
+
+        }
+
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/info_parser_utils.hpp b/include/boost/property_tree/detail/info_parser_utils.hpp
new file mode 100644
index 0000000..f30010e
--- /dev/null
+++ b/include/boost/property_tree/detail/info_parser_utils.hpp
@@ -0,0 +1,32 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED
+
+#include <string>
+
+namespace boost { namespace property_tree { namespace info_parser
+{
+
+    template<class ChDest, class ChSrc>
+    std::basic_string<ChDest> convert_chtype(const ChSrc *text)
+    {
+        std::basic_string<ChDest> result;
+        while (*text)
+        {
+            result += ChDest(*text);
+            ++text;
+        }
+        return result;
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/info_parser_write.hpp b/include/boost/property_tree/detail/info_parser_write.hpp
new file mode 100644
index 0000000..6abd72c
--- /dev/null
+++ b/include/boost/property_tree/detail/info_parser_write.hpp
@@ -0,0 +1,147 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
+
+#include "boost/property_tree/ptree.hpp"
+#include "boost/property_tree/detail/info_parser_utils.hpp"
+#include <string>
+
+namespace boost { namespace property_tree { namespace info_parser
+{
+    template<class Ch>
+    void write_info_indent(std::basic_ostream<Ch> &stream,
+          int indent,
+          const info_writer_settings<Ch> &settings
+          )
+    {
+        stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char);
+    }
+    
+    // Create necessary escape sequences from illegal characters
+    template<class Ch>
+    std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s)
+    {
+        std::basic_string<Ch> result;
+        typename std::basic_string<Ch>::const_iterator b = s.begin();
+        typename std::basic_string<Ch>::const_iterator e = s.end();
+        while (b != e)
+        {
+            if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0');
+            else if (*b == Ch('\a')) result += Ch('\\'), result += Ch('a');
+            else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
+            else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
+            else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
+            else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
+            else if (*b == Ch('\v')) result += Ch('\\'), result += Ch('v');
+            else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
+            else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
+            else
+                result += *b;
+            ++b;
+        }
+        return result;
+    }
+
+    template<class Ch>
+    bool is_simple_key(const std::basic_string<Ch> &key)
+    {
+        const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
+        return !key.empty() && key.find_first_of(chars) == key.npos;
+    }
+    
+    template<class Ch>
+    bool is_simple_data(const std::basic_string<Ch> &data)
+    {
+        const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
+        return !data.empty() && data.find_first_of(chars) == data.npos;
+    }
+
+    template<class Ptree>
+    void write_info_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream, 
+                           const Ptree &pt, 
+                           int indent,
+                           const info_writer_settings<typename Ptree::key_type::value_type> &settings)
+    {
+
+        // Character type
+        typedef typename Ptree::key_type::value_type Ch;
+        
+        // Write data
+        if (indent >= 0)
+        {
+            if (!pt.data().empty())
+            {
+                std::basic_string<Ch> data = create_escapes(pt.template get_value<std::basic_string<Ch> >());
+                if (is_simple_data(data))
+                    stream << Ch(' ') << data << Ch('\n');
+                else
+                    stream << Ch(' ') << Ch('\"') << data << Ch('\"') << Ch('\n');
+            }
+            else if (pt.empty())
+                stream << Ch(' ') << Ch('\"') << Ch('\"') << Ch('\n');
+            else
+                stream << Ch('\n');
+        }
+        
+        // Write keys
+        if (!pt.empty())
+        {
+            
+            // Open brace
+            if (indent >= 0)
+            {
+                write_info_indent( stream, indent, settings);
+                stream << Ch('{') << Ch('\n');
+            }
+            
+            // Write keys
+            typename Ptree::const_iterator it = pt.begin();
+            for (; it != pt.end(); ++it)
+            {
+
+                // Output key
+                std::basic_string<Ch> key = create_escapes(it->first);
+                write_info_indent( stream, indent+1, settings);
+                if (is_simple_key(key))
+                    stream << key;
+                else
+                    stream << Ch('\"') << key << Ch('\"');
+
+                // Output data and children  
+                write_info_helper(stream, it->second, indent + 1, settings);
+
+            }
+            
+            // Close brace
+            if (indent >= 0)
+            {
+                write_info_indent( stream, indent, settings);
+                stream << Ch('}') << Ch('\n');
+            }
+
+        }
+    }
+
+    // Write ptree to info stream
+    template<class Ptree>
+    void write_info_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream, 
+                             const Ptree &pt,
+                             const std::string &filename,
+                             const info_writer_settings<typename Ptree::key_type::value_type> &settings)
+    {
+        write_info_helper(stream, pt, -1, settings);
+        if (!stream.good())
+            BOOST_PROPERTY_TREE_THROW(info_parser_error("write error", filename, 0));
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/info_parser_writer_settings.hpp b/include/boost/property_tree/detail/info_parser_writer_settings.hpp
new file mode 100644
index 0000000..a391dae
--- /dev/null
+++ b/include/boost/property_tree/detail/info_parser_writer_settings.hpp
@@ -0,0 +1,40 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2007 Alexey Baskakov
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITER_SETTINGS_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITER_SETTINGS_HPP_INCLUDED
+
+#include <string>
+
+namespace boost { namespace property_tree { namespace info_parser
+{
+
+    template <class Ch>
+    class info_writer_settings
+    {
+    public:
+        info_writer_settings(Ch indent_char = Ch(' '), unsigned indent_count = 4):
+            indent_char(indent_char),
+            indent_count(indent_count)
+        {
+        }
+        Ch indent_char;
+        int indent_count;
+    };
+
+    template <class Ch>
+    info_writer_settings<Ch> info_writer_make_settings(Ch indent_char = Ch(' '), unsigned indent_count = 4)
+    {
+        return info_writer_settings<Ch>(indent_char, indent_count);
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/ptree_implementation.hpp b/include/boost/property_tree/detail/ptree_implementation.hpp
new file mode 100644
index 0000000..dd9fd37
--- /dev/null
+++ b/include/boost/property_tree/detail/ptree_implementation.hpp
@@ -0,0 +1,933 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
+
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+#include <boost/assert.hpp>
+#include <boost/utility/swap.hpp>
+#include <memory>
+
+#if (defined(BOOST_MSVC) && \
+     (_MSC_FULL_VER >= 160000000 && _MSC_FULL_VER < 170000000)) || \
+    (defined(BOOST_INTEL_WIN) && \
+     defined(BOOST_DINKUMWARE_STDLIB))
+#define BOOST_PROPERTY_TREE_PAIR_BUG
+#endif
+
+namespace boost { namespace property_tree
+{
+    template <class K, class D, class C>
+    struct basic_ptree<K, D, C>::subs
+    {
+        struct by_name {};
+        // The actual child container.
+#if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
+        // MSVC 10 has moved std::pair's members to a base
+        // class. Unfortunately this does break the interface.
+        BOOST_STATIC_CONSTANT(unsigned,
+            first_offset = offsetof(value_type, first));
+#endif
+        typedef multi_index_container<value_type,
+            multi_index::indexed_by<
+                multi_index::sequenced<>,
+                multi_index::ordered_non_unique<multi_index::tag<by_name>,
+#if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
+                    multi_index::member_offset<value_type, const key_type,
+                                        first_offset>,
+#else
+                    multi_index::member<value_type, const key_type,
+                                        &value_type::first>,
+#endif
+                    key_compare
+                >
+            >
+        > base_container;
+
+        // The by-name lookup index.
+        typedef typename base_container::template index<by_name>::type
+            by_name_index;
+
+        // Access functions for getting to the children of a tree.
+        static base_container& ch(self_type *s) {
+            return *static_cast<base_container*>(s->m_children);
+        }
+        static const base_container& ch(const self_type *s) {
+            return *static_cast<const base_container*>(s->m_children);
+        }
+        static by_name_index& assoc(self_type *s) {
+            return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
+        }
+        static const by_name_index& assoc(const self_type *s) {
+            return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
+        }
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::iterator : public boost::iterator_adaptor<
+        iterator, typename subs::base_container::iterator, value_type>
+    {
+        friend class boost::iterator_core_access;
+        typedef boost::iterator_adaptor<
+            iterator, typename subs::base_container::iterator, value_type>
+            baset;
+    public:
+        typedef typename baset::reference reference;
+        iterator() {}
+        explicit iterator(typename iterator::base_type b)
+            : iterator::iterator_adaptor_(b)
+        {}
+        reference dereference() const
+        {
+            // multi_index doesn't allow modification of its values, because
+            // indexes could sort by anything, and modification screws that up.
+            // However, we only sort by the key, and it's protected against
+            // modification in the value_type, so this const_cast is safe.
+            return const_cast<reference>(*this->base_reference());
+        }
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::const_iterator : public boost::iterator_adaptor<
+        const_iterator, typename subs::base_container::const_iterator>
+    {
+    public:
+        const_iterator() {}
+        explicit const_iterator(typename const_iterator::base_type b)
+            : const_iterator::iterator_adaptor_(b)
+        {}
+        const_iterator(iterator b)
+            : const_iterator::iterator_adaptor_(b.base())
+        {}
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::reverse_iterator
+        : public boost::reverse_iterator<iterator>
+    {
+    public:
+        reverse_iterator() {}
+        explicit reverse_iterator(iterator b)
+            : boost::reverse_iterator<iterator>(b)
+        {}
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::const_reverse_iterator
+        : public boost::reverse_iterator<const_iterator>
+    {
+    public:
+        const_reverse_iterator() {}
+        explicit const_reverse_iterator(const_iterator b)
+            : boost::reverse_iterator<const_iterator>(b)
+        {}
+        const_reverse_iterator(
+            typename basic_ptree<K, D, C>::reverse_iterator b)
+            : boost::reverse_iterator<const_iterator>(b)
+        {}
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::assoc_iterator
+        : public boost::iterator_adaptor<assoc_iterator,
+                                         typename subs::by_name_index::iterator,
+                                         value_type>
+    {
+        friend class boost::iterator_core_access;
+        typedef boost::iterator_adaptor<assoc_iterator,
+                                         typename subs::by_name_index::iterator,
+                                         value_type>
+            baset;
+    public:
+        typedef typename baset::reference reference;
+        assoc_iterator() {}
+        explicit assoc_iterator(typename assoc_iterator::base_type b)
+            : assoc_iterator::iterator_adaptor_(b)
+        {}
+        reference dereference() const
+        {
+            return const_cast<reference>(*this->base_reference());
+        }
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::const_assoc_iterator
+        : public boost::iterator_adaptor<const_assoc_iterator,
+                                   typename subs::by_name_index::const_iterator>
+    {
+    public:
+        const_assoc_iterator() {}
+        explicit const_assoc_iterator(
+            typename const_assoc_iterator::base_type b)
+            : const_assoc_iterator::iterator_adaptor_(b)
+        {}
+        const_assoc_iterator(assoc_iterator b)
+            : const_assoc_iterator::iterator_adaptor_(b.base())
+        {}
+    };
+
+
+    // Big five
+
+    // Perhaps the children collection could be created on-demand only, to
+    // reduce heap traffic. But that's a lot more work to implement.
+
+    template<class K, class D, class C> inline
+    basic_ptree<K, D, C>::basic_ptree()
+        : m_children(new typename subs::base_container)
+    {
+    }
+
+    template<class K, class D, class C> inline
+    basic_ptree<K, D, C>::basic_ptree(const data_type &d)
+        : m_data(d), m_children(new typename subs::base_container)
+    {
+    }
+
+    template<class K, class D, class C> inline
+    basic_ptree<K, D, C>::basic_ptree(const basic_ptree<K, D, C> &rhs)
+        : m_data(rhs.m_data),
+          m_children(new typename subs::base_container(subs::ch(&rhs)))
+    {
+    }
+
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::operator =(const basic_ptree<K, D, C> &rhs)
+    {
+        self_type(rhs).swap(*this);
+        return *this;
+    }
+
+    template<class K, class D, class C>
+    basic_ptree<K, D, C>::~basic_ptree()
+    {
+        delete &subs::ch(this);
+    }
+
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::swap(basic_ptree<K, D, C> &rhs)
+    {
+        boost::swap(m_data, rhs.m_data);
+        // Void pointers, no ADL necessary
+        std::swap(m_children, rhs.m_children);
+    }
+
+    // Container view
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::size_type
+        basic_ptree<K, D, C>::size() const
+    {
+        return subs::ch(this).size();
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::size_type
+        basic_ptree<K, D, C>::max_size() const
+    {
+        return subs::ch(this).max_size();
+    }
+
+    template<class K, class D, class C> inline
+    bool basic_ptree<K, D, C>::empty() const
+    {
+        return subs::ch(this).empty();
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::begin()
+    {
+        return iterator(subs::ch(this).begin());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_iterator
+        basic_ptree<K, D, C>::begin() const
+    {
+        return const_iterator(subs::ch(this).begin());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::end()
+    {
+        return iterator(subs::ch(this).end());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_iterator
+        basic_ptree<K, D, C>::end() const
+    {
+        return const_iterator(subs::ch(this).end());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::reverse_iterator
+        basic_ptree<K, D, C>::rbegin()
+    {
+        return reverse_iterator(this->end());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_reverse_iterator
+        basic_ptree<K, D, C>::rbegin() const
+    {
+        return const_reverse_iterator(this->end());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::reverse_iterator
+        basic_ptree<K, D, C>::rend()
+    {
+        return reverse_iterator(this->begin());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_reverse_iterator
+        basic_ptree<K, D, C>::rend() const
+    {
+        return const_reverse_iterator(this->begin());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::value_type &
+        basic_ptree<K, D, C>::front()
+    {
+        return const_cast<value_type&>(subs::ch(this).front());
+    }
+
+    template<class K, class D, class C> inline
+    const typename basic_ptree<K, D, C>::value_type &
+        basic_ptree<K, D, C>::front() const
+    {
+        return subs::ch(this).front();
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::value_type &
+        basic_ptree<K, D, C>::back()
+    {
+        return const_cast<value_type&>(subs::ch(this).back());
+    }
+
+    template<class K, class D, class C> inline
+    const typename basic_ptree<K, D, C>::value_type &
+        basic_ptree<K, D, C>::back() const
+    {
+        return subs::ch(this).back();
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+    basic_ptree<K, D, C>::insert(iterator where, const value_type &value)
+    {
+        return iterator(subs::ch(this).insert(where.base(), value).first);
+    }
+
+    template<class K, class D, class C>
+    template<class It> inline
+    void basic_ptree<K, D, C>::insert(iterator where, It first, It last)
+    {
+        subs::ch(this).insert(where.base(), first, last);
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::erase(iterator where)
+    {
+        return iterator(subs::ch(this).erase(where.base()));
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::erase(iterator first, iterator last)
+    {
+        return iterator(subs::ch(this).erase(first.base(), last.base()));
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::push_front(const value_type &value)
+    {
+        return iterator(subs::ch(this).push_front(value).first);
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::push_back(const value_type &value)
+    {
+        return iterator(subs::ch(this).push_back(value).first);
+    }
+
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::pop_front()
+    {
+        subs::ch(this).pop_front();
+    }
+
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::pop_back()
+    {
+        subs::ch(this).pop_back();
+    }
+
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::reverse()
+    {
+        subs::ch(this).reverse();
+    }
+
+    namespace impl
+    {
+        struct by_first
+        {
+            template <typename P>
+            bool operator ()(const P& lhs, const P& rhs) const {
+              return lhs.first < rhs.first;
+            }
+        };
+
+        template <typename C>
+        struct equal_pred
+        {
+            template <typename P>
+            bool operator ()(const P& lhs, const P& rhs) const {
+                C c;
+                return !c(lhs.first, rhs.first) &&
+                       !c(rhs.first, lhs.first) &&
+                       lhs.second == rhs.second;
+            }
+        };
+
+        template <typename C, typename MI>
+        bool equal_children(const MI& ch1, const MI& ch2) {
+            // Assumes ch1.size() == ch2.size()
+            return std::equal(ch1.begin(), ch1.end(),
+                ch2.begin(), equal_pred<C>());
+        }
+    }
+
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::sort()
+    {
+        sort(impl::by_first());
+    }
+
+    template<class K, class D, class C>
+    template<class Compare> inline
+    void basic_ptree<K, D, C>::sort(Compare comp)
+    {
+        subs::ch(this).sort(comp);
+    }
+
+    // Equality
+
+    template<class K, class D, class C> inline
+    bool basic_ptree<K, D, C>::operator ==(
+                                  const basic_ptree<K, D, C> &rhs) const
+    {
+        // The size test is cheap, so add it as an optimization
+        return size() == rhs.size() && data() == rhs.data() &&
+            impl::equal_children<C>(subs::ch(this), subs::ch(&rhs));
+    }
+
+    template<class K, class D, class C> inline
+    bool basic_ptree<K, D, C>::operator !=(
+                                  const basic_ptree<K, D, C> &rhs) const
+    {
+        return !(*this == rhs);
+    }
+
+    // Associative view
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::assoc_iterator
+        basic_ptree<K, D, C>::ordered_begin()
+    {
+        return assoc_iterator(subs::assoc(this).begin());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_assoc_iterator
+        basic_ptree<K, D, C>::ordered_begin() const
+    {
+        return const_assoc_iterator(subs::assoc(this).begin());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::assoc_iterator
+        basic_ptree<K, D, C>::not_found()
+    {
+        return assoc_iterator(subs::assoc(this).end());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_assoc_iterator
+        basic_ptree<K, D, C>::not_found() const
+    {
+        return const_assoc_iterator(subs::assoc(this).end());
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::assoc_iterator
+        basic_ptree<K, D, C>::find(const key_type &key)
+    {
+        return assoc_iterator(subs::assoc(this).find(key));
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_assoc_iterator
+        basic_ptree<K, D, C>::find(const key_type &key) const
+    {
+        return const_assoc_iterator(subs::assoc(this).find(key));
+    }
+
+    template<class K, class D, class C> inline
+    std::pair<
+        typename basic_ptree<K, D, C>::assoc_iterator,
+        typename basic_ptree<K, D, C>::assoc_iterator
+    > basic_ptree<K, D, C>::equal_range(const key_type &key)
+    {
+        std::pair<typename subs::by_name_index::iterator,
+                  typename subs::by_name_index::iterator> r(
+            subs::assoc(this).equal_range(key));
+        return std::pair<assoc_iterator, assoc_iterator>(
+          assoc_iterator(r.first), assoc_iterator(r.second));
+    }
+
+    template<class K, class D, class C> inline
+    std::pair<
+        typename basic_ptree<K, D, C>::const_assoc_iterator,
+        typename basic_ptree<K, D, C>::const_assoc_iterator
+    > basic_ptree<K, D, C>::equal_range(const key_type &key) const
+    {
+        std::pair<typename subs::by_name_index::const_iterator,
+                  typename subs::by_name_index::const_iterator> r(
+            subs::assoc(this).equal_range(key));
+        return std::pair<const_assoc_iterator, const_assoc_iterator>(
+            const_assoc_iterator(r.first), const_assoc_iterator(r.second));
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::size_type
+        basic_ptree<K, D, C>::count(const key_type &key) const
+    {
+        return subs::assoc(this).count(key);
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::size_type
+        basic_ptree<K, D, C>::erase(const key_type &key)
+    {
+        return subs::assoc(this).erase(key);
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::to_iterator(assoc_iterator ai)
+    {
+        return iterator(subs::ch(this).
+            BOOST_NESTED_TEMPLATE project<0>(ai.base()));
+    }
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_iterator
+        basic_ptree<K, D, C>::to_iterator(const_assoc_iterator ai) const
+    {
+        return const_iterator(subs::ch(this).
+            BOOST_NESTED_TEMPLATE project<0>(ai.base()));
+    }
+
+    // Property tree view
+
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::data_type &
+        basic_ptree<K, D, C>::data()
+    {
+        return m_data;
+    }
+
+    template<class K, class D, class C> inline
+    const typename basic_ptree<K, D, C>::data_type &
+        basic_ptree<K, D, C>::data() const
+    {
+        return m_data;
+    }
+
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::clear()
+    {
+        m_data = data_type();
+        subs::ch(this).clear();
+    }
+
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::get_child(const path_type &path)
+    {
+        path_type p(path);
+        self_type *n = walk_path(p);
+        if (!n) {
+            BOOST_PROPERTY_TREE_THROW(ptree_bad_path("No such node", path));
+        }
+        return *n;
+    }
+
+    template<class K, class D, class C> inline
+    const basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::get_child(const path_type &path) const
+    {
+        return const_cast<self_type*>(this)->get_child(path);
+    }
+
+    template<class K, class D, class C> inline
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::get_child(const path_type &path,
+                                        self_type &default_value)
+    {
+        path_type p(path);
+        self_type *n = walk_path(p);
+        return n ? *n : default_value;
+    }
+
+    template<class K, class D, class C> inline
+    const basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::get_child(const path_type &path,
+                                        const self_type &default_value) const
+    {
+        return const_cast<self_type*>(this)->get_child(path,
+            const_cast<self_type&>(default_value));
+    }
+
+
+    template<class K, class D, class C>
+    optional<basic_ptree<K, D, C> &>
+        basic_ptree<K, D, C>::get_child_optional(const path_type &path)
+    {
+        path_type p(path);
+        self_type *n = walk_path(p);
+        if (!n) {
+            return optional<self_type&>();
+        }
+        return *n;
+    }
+
+    template<class K, class D, class C>
+    optional<const basic_ptree<K, D, C> &>
+        basic_ptree<K, D, C>::get_child_optional(const path_type &path) const
+    {
+        path_type p(path);
+        self_type *n = walk_path(p);
+        if (!n) {
+            return optional<const self_type&>();
+        }
+        return *n;
+    }
+
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::put_child(const path_type &path,
+                                        const self_type &value)
+    {
+        path_type p(path);
+        self_type &parent = force_path(p);
+        // Got the parent. Now get the correct child.
+        key_type fragment = p.reduce();
+        assoc_iterator el = parent.find(fragment);
+        // If the new child exists, replace it.
+        if(el != parent.not_found()) {
+            return el->second = value;
+        } else {
+            return parent.push_back(value_type(fragment, value))->second;
+        }
+    }
+
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::add_child(const path_type &path,
+                                        const self_type &value)
+    {
+        path_type p(path);
+        self_type &parent = force_path(p);
+        // Got the parent.
+        key_type fragment = p.reduce();
+        return parent.push_back(value_type(fragment, value))->second;
+    }
+
+    template<class K, class D, class C>
+    template<class Type, class Translator>
+    typename boost::enable_if<detail::is_translator<Translator>, Type>::type
+    basic_ptree<K, D, C>::get_value(Translator tr) const
+    {
+        if(boost::optional<Type> o = get_value_optional<Type>(tr)) {
+            return *o;
+        }
+        BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
+            std::string("conversion of data to type \"") +
+            typeid(Type).name() + "\" failed", data()));
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    Type basic_ptree<K, D, C>::get_value() const
+    {
+        return get_value<Type>(
+            typename translator_between<data_type, Type>::type());
+    }
+
+    template<class K, class D, class C>
+    template<class Type, class Translator> inline
+    Type basic_ptree<K, D, C>::get_value(const Type &default_value,
+                                         Translator tr) const
+    {
+        return get_value_optional<Type>(tr).get_value_or(default_value);
+    }
+
+    template<class K, class D, class C>
+    template <class Ch, class Translator>
+    typename boost::enable_if<
+        detail::is_character<Ch>,
+        std::basic_string<Ch>
+    >::type
+    basic_ptree<K, D, C>::get_value(const Ch *default_value, Translator tr)const
+    {
+        return get_value<std::basic_string<Ch>, Translator>(default_value, tr);
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    typename boost::disable_if<detail::is_translator<Type>, Type>::type
+    basic_ptree<K, D, C>::get_value(const Type &default_value) const
+    {
+        return get_value(default_value,
+                         typename translator_between<data_type, Type>::type());
+    }
+
+    template<class K, class D, class C>
+    template <class Ch>
+    typename boost::enable_if<
+        detail::is_character<Ch>,
+        std::basic_string<Ch>
+    >::type
+    basic_ptree<K, D, C>::get_value(const Ch *default_value) const
+    {
+        return get_value< std::basic_string<Ch> >(default_value);
+    }
+
+    template<class K, class D, class C>
+    template<class Type, class Translator> inline
+    optional<Type> basic_ptree<K, D, C>::get_value_optional(
+                                                Translator tr) const
+    {
+        return tr.get_value(data());
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    optional<Type> basic_ptree<K, D, C>::get_value_optional() const
+    {
+        return get_value_optional<Type>(
+            typename translator_between<data_type, Type>::type());
+    }
+
+    template<class K, class D, class C>
+    template<class Type, class Translator> inline
+    typename boost::enable_if<detail::is_translator<Translator>, Type>::type
+    basic_ptree<K, D, C>::get(const path_type &path,
+                              Translator tr) const
+    {
+        return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>(tr);
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    Type basic_ptree<K, D, C>::get(const path_type &path) const
+    {
+        return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>();
+    }
+
+    template<class K, class D, class C>
+    template<class Type, class Translator> inline
+    Type basic_ptree<K, D, C>::get(const path_type &path,
+                                   const Type &default_value,
+                                   Translator tr) const
+    {
+        return get_optional<Type>(path, tr).get_value_or(default_value);
+    }
+
+    template<class K, class D, class C>
+    template <class Ch, class Translator>
+    typename boost::enable_if<
+        detail::is_character<Ch>,
+        std::basic_string<Ch>
+    >::type
+    basic_ptree<K, D, C>::get(
+        const path_type &path, const Ch *default_value, Translator tr) const
+    {
+        return get<std::basic_string<Ch>, Translator>(path, default_value, tr);
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    typename boost::disable_if<detail::is_translator<Type>, Type>::type
+    basic_ptree<K, D, C>::get(const path_type &path,
+                              const Type &default_value) const
+    {
+        return get_optional<Type>(path).get_value_or(default_value);
+    }
+
+    template<class K, class D, class C>
+    template <class Ch>
+    typename boost::enable_if<
+        detail::is_character<Ch>,
+        std::basic_string<Ch>
+    >::type
+    basic_ptree<K, D, C>::get(
+        const path_type &path, const Ch *default_value) const
+    {
+        return get< std::basic_string<Ch> >(path, default_value);
+    }
+
+    template<class K, class D, class C>
+    template<class Type, class Translator>
+    optional<Type> basic_ptree<K, D, C>::get_optional(const path_type &path,
+                                                         Translator tr) const
+    {
+        if (optional<const self_type&> child = get_child_optional(path))
+            return child.get().
+                BOOST_NESTED_TEMPLATE get_value_optional<Type>(tr);
+        else
+            return optional<Type>();
+    }
+
+    template<class K, class D, class C>
+    template<class Type>
+    optional<Type> basic_ptree<K, D, C>::get_optional(
+                                                const path_type &path) const
+    {
+        if (optional<const self_type&> child = get_child_optional(path))
+            return child.get().BOOST_NESTED_TEMPLATE get_value_optional<Type>();
+        else
+            return optional<Type>();
+    }
+
+    template<class K, class D, class C>
+    template<class Type, class Translator>
+    void basic_ptree<K, D, C>::put_value(const Type &value, Translator tr)
+    {
+        if(optional<data_type> o = tr.put_value(value)) {
+            data() = *o;
+        } else {
+            BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
+                std::string("conversion of type \"") + typeid(Type).name() +
+                "\" to data failed", boost::any()));
+        }
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    void basic_ptree<K, D, C>::put_value(const Type &value)
+    {
+        put_value(value, typename translator_between<data_type, Type>::type());
+    }
+
+    template<class K, class D, class C>
+    template<class Type, typename Translator>
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
+        const path_type &path, const Type &value, Translator tr)
+    {
+        if(optional<self_type &> child = get_child_optional(path)) {
+            child.get().put_value(value, tr);
+            return *child;
+        } else {
+            self_type &child2 = put_child(path, self_type());
+            child2.put_value(value, tr);
+            return child2;
+        }
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
+        const path_type &path, const Type &value)
+    {
+        return put(path, value,
+                   typename translator_between<data_type, Type>::type());
+    }
+
+    template<class K, class D, class C>
+    template<class Type, typename Translator> inline
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
+        const path_type &path, const Type &value, Translator tr)
+    {
+        self_type &child = add_child(path, self_type());
+        child.put_value(value, tr);
+        return child;
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
+        const path_type &path, const Type &value)
+    {
+        return add(path, value,
+                   typename translator_between<data_type, Type>::type());
+    }
+
+
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> *
+    basic_ptree<K, D, C>::walk_path(path_type &p) const
+    {
+        if(p.empty()) {
+            // I'm the child we're looking for.
+            return const_cast<basic_ptree*>(this);
+        }
+        // Recurse down the tree to find the path.
+        key_type fragment = p.reduce();
+        const_assoc_iterator el = find(fragment);
+        if(el == not_found()) {
+            // No such child.
+            return 0;
+        }
+        // Not done yet, recurse.
+        return el->second.walk_path(p);
+    }
+
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::force_path(path_type &p)
+    {
+        BOOST_ASSERT(!p.empty() && "Empty path not allowed for put_child.");
+        if(p.single()) {
+            // I'm the parent we're looking for.
+            return *this;
+        }
+        key_type fragment = p.reduce();
+        assoc_iterator el = find(fragment);
+        // If we've found an existing child, go down that path. Else
+        // create a new one.
+        self_type& child = el == not_found() ?
+            push_back(value_type(fragment, self_type()))->second : el->second;
+        return child.force_path(p);
+    }
+
+    // Free functions
+
+    template<class K, class D, class C>
+    inline void swap(basic_ptree<K, D, C> &pt1, basic_ptree<K, D, C> &pt2)
+    {
+        pt1.swap(pt2);
+    }
+
+} }
+
+#if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
+#undef BOOST_PROPERTY_TREE_PAIR_BUG
+#endif
+
+#endif
diff --git a/include/boost/property_tree/detail/ptree_utils.hpp b/include/boost/property_tree/detail/ptree_utils.hpp
new file mode 100644
index 0000000..c353e08
--- /dev/null
+++ b/include/boost/property_tree/detail/ptree_utils.hpp
@@ -0,0 +1,105 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
+
+#include <boost/limits.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/and.hpp>
+#include <string>
+#include <algorithm>
+#include <locale>
+
+namespace boost { namespace property_tree { namespace detail
+{
+
+    template<class T>
+    struct less_nocase
+    {
+        typedef typename T::value_type Ch;
+        std::locale m_locale;
+        inline bool operator()(Ch c1, Ch c2) const
+        {
+            return std::toupper(c1, m_locale) < std::toupper(c2, m_locale);
+        }
+        inline bool operator()(const T &t1, const T &t2) const
+        {
+            return std::lexicographical_compare(t1.begin(), t1.end(),
+                                                t2.begin(), t2.end(), *this);
+        }
+    };
+
+    template <typename Ch>
+    struct is_character : public boost::false_type {};
+    template <>
+    struct is_character<char> : public boost::true_type {};
+    template <>
+    struct is_character<wchar_t> : public boost::true_type {};
+
+
+    BOOST_MPL_HAS_XXX_TRAIT_DEF(internal_type)
+    BOOST_MPL_HAS_XXX_TRAIT_DEF(external_type)
+    template <typename T>
+    struct is_translator : public boost::mpl::and_<
+        has_internal_type<T>, has_external_type<T> > {};
+
+
+
+    // Naively convert narrow string to another character type
+    template<typename Str>
+    Str widen(const char *text)
+    {
+        Str result;
+        while (*text)
+        {
+            result += typename Str::value_type(*text);
+            ++text;
+        }
+        return result;
+    }
+
+    // Naively convert string to narrow character type
+    template<typename Str, typename char_type>
+    Str narrow(const char_type *text)
+    {
+        Str result;
+        while (*text)
+        {
+            if (*text < 0 || *text > (std::numeric_limits<char>::max)())
+                result += '*';
+            else
+                result += typename Str::value_type(*text);
+            ++text;
+        }
+        return result;
+    }
+
+    // Remove trailing and leading spaces
+    template<class Str>
+    Str trim(const Str &s, const std::locale &loc = std::locale())
+    {
+        typename Str::const_iterator first = s.begin();
+        typename Str::const_iterator end = s.end();
+        while (first != end && std::isspace(*first, loc))
+            ++first;
+        if (first == end)
+            return Str();
+        typename Str::const_iterator last = end;
+        do --last; while (std::isspace(*last, loc));
+        if (first != s.begin() || last + 1 != end)
+            return Str(first, last + 1);
+        else
+            return s;
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/rapidxml.hpp b/include/boost/property_tree/detail/rapidxml.hpp
new file mode 100644
index 0000000..9e3d76a
--- /dev/null
+++ b/include/boost/property_tree/detail/rapidxml.hpp
@@ -0,0 +1,2595 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2006, 2009 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED
+
+//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation
+
+#include <boost/assert.hpp>
+#include <cstdlib>      // For std::size_t
+#include <new>          // For placement new
+
+// On MSVC, disable "conditional expression is constant" warning (level 4). 
+// This warning is almost impossible to avoid with certain types of templated code
+#ifdef _MSC_VER
+    #pragma warning(push)
+    #pragma warning(disable:4127)   // Conditional expression is constant
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+// BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR
+    
+#include <exception>    // For std::exception
+
+#define BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)
+
+namespace boost { namespace property_tree { namespace detail {namespace rapidxml
+{
+
+    //! Parse error exception. 
+    //! This exception is thrown by the parser when an error occurs. 
+    //! Use what() function to get human-readable error message. 
+    //! Use where() function to get a pointer to position within source text where error was detected.
+    //! <br><br>
+    //! If throwing exceptions by the parser is undesirable, 
+    //! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included.
+    //! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception.
+    //! This function must be defined by the user.
+    //! <br><br>
+    //! This class derives from <code>std::exception</code> class.
+    class parse_error: public std::exception
+    {
+    
+    public:
+    
+        //! Constructs parse error
+        parse_error(const char *wa, void *we)
+            : m_what(wa)
+            , m_where(we)
+        {
+        }
+
+        //! Gets human readable description of error.
+        //! \return Pointer to null terminated description of the error.
+        virtual const char *what() const throw()
+        {
+            return m_what;
+        }
+
+        //! Gets pointer to character data where error happened.
+        //! Ch should be the same as char type of xml_document that produced the error.
+        //! \return Pointer to location within the parsed string where error occurred.
+        template<class Ch>
+        Ch *where() const
+        {
+            return reinterpret_cast<Ch *>(m_where);
+        }
+
+    private:  
+
+        const char *m_what;
+        void *m_where;
+
+    };
+}}}}
+
+///////////////////////////////////////////////////////////////////////////
+// Pool sizes
+
+#ifndef BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE
+    // Size of static memory block of memory_pool.
+    // Define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
+    // No dynamic memory allocations are performed by memory_pool until static memory is exhausted.
+    #define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE (64 * 1024)
+#endif
+
+#ifndef BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE
+    // Size of dynamic memory block of memory_pool.
+    // Define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
+    // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool.
+    #define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)
+#endif
+
+#ifndef BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT
+    // Memory allocation alignment.
+    // Define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer.
+    // All memory allocations for nodes, attributes and strings will be aligned to this value.
+    // This must be a power of 2 and at least 1, otherwise memory_pool will not work.
+    #define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT sizeof(void *)
+#endif
+
+namespace boost { namespace property_tree { namespace detail {namespace rapidxml
+{
+    // Forward declarations
+    template<class Ch> class xml_node;
+    template<class Ch> class xml_attribute;
+    template<class Ch> class xml_document;
+    
+    //! Enumeration listing all node types produced by the parser.
+    //! Use xml_node::type() function to query node type.
+    enum node_type
+    {
+        node_document,      //!< A document node. Name and value are empty.
+        node_element,       //!< An element node. Name contains element name. Value contains text of first data node.
+        node_data,          //!< A data node. Name is empty. Value contains data text.
+        node_cdata,         //!< A CDATA node. Name is empty. Value contains data text.
+        node_comment,       //!< A comment node. Name is empty. Value contains comment text.
+        node_declaration,   //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes.
+        node_doctype,       //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text.
+        node_pi             //!< A PI node. Name contains target. Value contains instructions.
+    };
+
+    ///////////////////////////////////////////////////////////////////////
+    // Parsing flags
+
+    //! Parse flag instructing the parser to not create data nodes. 
+    //! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_no_data_nodes = 0x1;            
+
+    //! Parse flag instructing the parser to not use text of first data node as a value of parent element.
+    //! Can be combined with other flags by use of | operator.
+    //! Note that child data nodes of element node take precendence over its value when printing. 
+    //! That is, if element has one or more child data nodes <em>and</em> a value, the value will be ignored.
+    //! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_no_element_values = 0x2;
+    
+    //! Parse flag instructing the parser to not place zero terminators after strings in the source text.
+    //! By default zero terminators are placed, modifying source text.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_no_string_terminators = 0x4;
+    
+    //! Parse flag instructing the parser to not translate entities in the source text.
+    //! By default entities are translated, modifying source text.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_no_entity_translation = 0x8;
+    
+    //! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters.
+    //! By default, UTF-8 handling is enabled.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_no_utf8 = 0x10;
+    
+    //! Parse flag instructing the parser to create XML declaration node.
+    //! By default, declaration node is not created.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_declaration_node = 0x20;
+    
+    //! Parse flag instructing the parser to create comments nodes.
+    //! By default, comment nodes are not created.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_comment_nodes = 0x40;
+    
+    //! Parse flag instructing the parser to create DOCTYPE node.
+    //! By default, doctype node is not created.
+    //! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_doctype_node = 0x80;
+    
+    //! Parse flag instructing the parser to create PI nodes.
+    //! By default, PI nodes are not created.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_pi_nodes = 0x100;
+    
+    //! Parse flag instructing the parser to validate closing tag names. 
+    //! If not set, name inside closing tag is irrelevant to the parser.
+    //! By default, closing tags are not validated.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_validate_closing_tags = 0x200;
+    
+    //! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes.
+    //! By default, whitespace is not trimmed. 
+    //! This flag does not cause the parser to modify source text.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_trim_whitespace = 0x400;
+
+    //! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character.
+    //! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag.
+    //! By default, whitespace is not normalized. 
+    //! If this flag is specified, source text will be modified.
+    //! Can be combined with other flags by use of | operator.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_normalize_whitespace = 0x800;
+
+    // Compound flags
+    
+    //! Parse flags which represent default behaviour of the parser. 
+    //! This is always equal to 0, so that all other flags can be simply ored together.
+    //! Normally there is no need to inconveniently disable flags by anding with their negated (~) values.
+    //! This also means that meaning of each flag is a <i>negation</i> of the default setting. 
+    //! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is <i>enabled</i> by default,
+    //! and using the flag will disable it.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_default = 0;
+    
+    //! A combination of parse flags that forbids any modifications of the source text. 
+    //! This also results in faster parsing. However, note that the following will occur:
+    //! <ul>
+    //! <li>names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends</li>
+    //! <li>entities will not be translated</li>
+    //! <li>whitespace will not be normalized</li>
+    //! </ul>
+    //! See xml_document::parse() function.
+    const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation;
+    
+    //! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_fastest = parse_non_destructive | parse_no_data_nodes;
+    
+    //! A combination of parse flags resulting in largest amount of data being extracted. 
+    //! This usually results in slowest parsing.
+    //! <br><br>
+    //! See xml_document::parse() function.
+    const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;
+
+    ///////////////////////////////////////////////////////////////////////
+    // Internals
+
+    //! \cond internal
+    namespace internal
+    {
+
+        // Struct that contains lookup tables for the parser
+        // It must be a template to allow correct linking (because it has static data members, which are defined in a header file).
+        template<int Dummy>
+        struct lookup_tables
+        {
+            static const unsigned char lookup_whitespace[256];              // Whitespace table
+            static const unsigned char lookup_node_name[256];               // Node name table
+            static const unsigned char lookup_text[256];                    // Text table
+            static const unsigned char lookup_text_pure_no_ws[256];         // Text table
+            static const unsigned char lookup_text_pure_with_ws[256];       // Text table
+            static const unsigned char lookup_attribute_name[256];          // Attribute name table
+            static const unsigned char lookup_attribute_data_1[256];        // Attribute data table with single quote
+            static const unsigned char lookup_attribute_data_1_pure[256];   // Attribute data table with single quote
+            static const unsigned char lookup_attribute_data_2[256];        // Attribute data table with double quotes
+            static const unsigned char lookup_attribute_data_2_pure[256];   // Attribute data table with double quotes
+            static const unsigned char lookup_digits[256];                  // Digits
+            static const unsigned char lookup_upcase[256];                  // To uppercase conversion table for ASCII characters
+        };
+
+        // Find length of the string
+        template<class Ch>
+        inline std::size_t measure(const Ch *p)
+        {
+            const Ch *tmp = p;
+            while (*tmp) 
+                ++tmp;
+            return tmp - p;
+        }
+
+        // Compare strings for equality
+        template<class Ch>
+        inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive)
+        {
+            if (size1 != size2)
+                return false;
+            if (case_sensitive)
+            {
+                for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
+                    if (*p1 != *p2)
+                        return false;
+            }
+            else
+            {
+                for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
+                    if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)] != lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])
+                        return false;
+            }
+            return true;
+        }
+
+        template<class Ch>
+        inline size_t get_index(const Ch c)
+        {
+            // If not ASCII char, its semantic is same as plain 'z'.
+            // char could be signed, so first stretch and make unsigned.
+            unsigned n = c;
+            if (n > 127)
+            {
+                return 'z';
+            }
+            return c;
+        }
+    }
+    //! \endcond
+
+    ///////////////////////////////////////////////////////////////////////
+    // Memory pool
+    
+    //! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation.
+    //! In most cases, you will not need to use this class directly. 
+    //! However, if you need to create nodes manually or modify names/values of nodes, 
+    //! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. 
+    //! Not only is this faster than allocating them by using <code>new</code> operator, 
+    //! but also their lifetime will be tied to the lifetime of document, 
+    //! possibly simplyfing memory management. 
+    //! <br><br>
+    //! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. 
+    //! You can also call allocate_string() function to allocate strings.
+    //! Such strings can then be used as names or values of nodes without worrying about their lifetime.
+    //! Note that there is no <code>free()</code> function -- all allocations are freed at once when clear() function is called, 
+    //! or when the pool is destroyed.
+    //! <br><br>
+    //! It is also possible to create a standalone memory_pool, and use it 
+    //! to allocate nodes, whose lifetime will not be tied to any document.
+    //! <br><br>
+    //! Pool maintains <code>BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE</code> bytes of statically allocated memory. 
+    //! Until static memory is exhausted, no dynamic memory allocations are done.
+    //! When static memory is exhausted, pool allocates additional blocks of memory of size <code>BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE</code> each,
+    //! by using global <code>new[]</code> and <code>delete[]</code> operators. 
+    //! This behaviour can be changed by setting custom allocation routines. 
+    //! Use set_allocator() function to set them.
+    //! <br><br>
+    //! Allocations for nodes, attributes and strings are aligned at <code>BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT</code> bytes.
+    //! This value defaults to the size of pointer on target architecture.
+    //! <br><br>
+    //! To obtain absolutely top performance from the parser,
+    //! it is important that all nodes are allocated from a single, contiguous block of memory.
+    //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably.
+    //! If required, you can tweak <code>BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE</code>, <code>BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE</code> and <code>BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT</code> 
+    //! to obtain best wasted memory to performance compromise.
+    //! To do it, define their values before rapidxml.hpp file is included.
+    //! \param Ch Character type of created nodes. 
+    template<class Ch = char>
+    class memory_pool
+    {
+        
+    public:
+
+        //! \cond internal
+        // Prefixed names to work around weird MSVC lookup bug.
+        typedef void *(boost_ptree_raw_alloc_func)(std::size_t);       // Type of user-defined function used to allocate memory
+        typedef void (boost_ptree_raw_free_func)(void *);              // Type of user-defined function used to free memory
+        //! \endcond
+        
+        //! Constructs empty pool with default allocator functions.
+        memory_pool()
+            : m_alloc_func(0)
+            , m_free_func(0)
+        {
+            init();
+        }
+
+        //! Destroys pool and frees all the memory. 
+        //! This causes memory occupied by nodes allocated by the pool to be freed.
+        //! Nodes allocated from the pool are no longer valid.
+        ~memory_pool()
+        {
+            clear();
+        }
+
+        //! Allocates a new node from the pool, and optionally assigns name and value to it. 
+        //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+        //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+        //! will call rapidxml::parse_error_handler() function.
+        //! \param type Type of node to create.
+        //! \param name Name to assign to the node, or 0 to assign no name.
+        //! \param value Value to assign to the node, or 0 to assign no value.
+        //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
+        //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
+        //! \return Pointer to allocated node. This pointer will never be NULL.
+        xml_node<Ch> *allocate_node(node_type type, 
+                                    const Ch *name = 0, const Ch *value = 0, 
+                                    std::size_t name_size = 0, std::size_t value_size = 0)
+        {
+            void *memory = allocate_aligned(sizeof(xml_node<Ch>));
+            xml_node<Ch> *node = new(memory) xml_node<Ch>(type);
+            if (name)
+            {
+                if (name_size > 0)
+                    node->name(name, name_size);
+                else
+                    node->name(name);
+            }
+            if (value)
+            {
+                if (value_size > 0)
+                    node->value(value, value_size);
+                else
+                    node->value(value);
+            }
+            return node;
+        }
+
+        //! Allocates a new attribute from the pool, and optionally assigns name and value to it.
+        //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+        //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+        //! will call rapidxml::parse_error_handler() function.
+        //! \param name Name to assign to the attribute, or 0 to assign no name.
+        //! \param value Value to assign to the attribute, or 0 to assign no value.
+        //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
+        //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
+        //! \return Pointer to allocated attribute. This pointer will never be NULL.
+        xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0, 
+                                              std::size_t name_size = 0, std::size_t value_size = 0)
+        {
+            void *memory = allocate_aligned(sizeof(xml_attribute<Ch>));
+            xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>;
+            if (name)
+            {
+                if (name_size > 0)
+                    attribute->name(name, name_size);
+                else
+                    attribute->name(name);
+            }
+            if (value)
+            {
+                if (value_size > 0)
+                    attribute->value(value, value_size);
+                else
+                    attribute->value(value);
+            }
+            return attribute;
+        }
+
+        //! Allocates a char array of given size from the pool, and optionally copies a given string to it.
+        //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+        //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+        //! will call rapidxml::parse_error_handler() function.
+        //! \param source String to initialize the allocated memory with, or 0 to not initialize it.
+        //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated.
+        //! \return Pointer to allocated char array. This pointer will never be NULL.
+        Ch *allocate_string(const Ch *source = 0, std::size_t size = 0)
+        {
+            BOOST_ASSERT(source || size);     // Either source or size (or both) must be specified
+            if (size == 0)
+                size = internal::measure(source) + 1;
+            Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
+            if (source)
+                for (std::size_t i = 0; i < size; ++i)
+                    result[i] = source[i];
+            return result;
+        }
+
+        //! Clones an xml_node and its hierarchy of child nodes and attributes.
+        //! Nodes and attributes are allocated from this memory pool.
+        //! Names and values are not cloned, they are shared between the clone and the source.
+        //! Result node can be optionally specified as a second parameter, 
+        //! in which case its contents will be replaced with cloned source node.
+        //! This is useful when you want to clone entire document.
+        //! \param source Node to clone.
+        //! \param result Node to put results in, or 0 to automatically allocate result node
+        //! \return Pointer to cloned node. This pointer will never be NULL.
+        xml_node<Ch> *clone_node(const xml_node<Ch> *source, xml_node<Ch> *result = 0)
+        {
+            // Prepare result node
+            if (result)
+            {
+                result->remove_all_attributes();
+                result->remove_all_nodes();
+                result->type(source->type());
+            }
+            else
+                result = allocate_node(source->type());
+
+            // Clone name and value
+            result->name(source->name(), source->name_size());
+            result->value(source->value(), source->value_size());
+
+            // Clone child nodes and attributes
+            for (xml_node<Ch> *child = source->first_node(); child; child = child->next_sibling())
+                result->append_node(clone_node(child));
+            for (xml_attribute<Ch> *attr = source->first_attribute(); attr; attr = attr->next_attribute())
+                result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size()));
+
+            return result;
+        }
+
+        //! Clears the pool. 
+        //! This causes memory occupied by nodes allocated by the pool to be freed.
+        //! Any nodes or strings allocated from the pool will no longer be valid.
+        void clear()
+        {
+            while (m_begin != m_static_memory)
+            {
+                char *previous_begin = reinterpret_cast<header *>(align(m_begin))->previous_begin;
+                if (m_free_func)
+                    m_free_func(m_begin);
+                else
+                    delete[] m_begin;
+                m_begin = previous_begin;
+            }
+            init();
+        }
+
+        //! Sets or resets the user-defined memory allocation functions for the pool.
+        //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined.
+        //! Allocation function must not return invalid pointer on failure. It should either throw,
+        //! stop the program, or use <code>longjmp()</code> function to pass control to other place of program. 
+        //! If it returns invalid pointer, results are undefined.
+        //! <br><br>
+        //! User defined allocation functions must have the following forms:
+        //! <br><code>
+        //! <br>void *allocate(std::size_t size);
+        //! <br>void free(void *pointer);
+        //! </code><br>
+        //! \param af Allocation function, or 0 to restore default function
+        //! \param ff Free function, or 0 to restore default function
+        void set_allocator(boost_ptree_raw_alloc_func *af, boost_ptree_raw_free_func *ff)
+        {
+            BOOST_ASSERT(m_begin == m_static_memory && m_ptr == align(m_begin));    // Verify that no memory is allocated yet
+            m_alloc_func = af;
+            m_free_func = ff;
+        }
+
+    private:
+
+        struct header
+        {
+            char *previous_begin;
+        };
+
+        void init()
+        {
+            m_begin = m_static_memory;
+            m_ptr = align(m_begin);
+            m_end = m_static_memory + sizeof(m_static_memory);
+        }
+        
+        char *align(char *ptr)
+        {
+            std::size_t alignment = ((BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 1))) & (BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 1));
+            return ptr + alignment;
+        }
+        
+        char *allocate_raw(std::size_t size)
+        {
+            // Allocate
+            void *memory;   
+            if (m_alloc_func)   // Allocate memory using either user-specified allocation function or global operator new[]
+            {
+                memory = m_alloc_func(size);
+                BOOST_ASSERT(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp
+            }
+            else
+            {
+                memory = new char[size];
+            }
+            return static_cast<char *>(memory);
+        }
+        
+        void *allocate_aligned(std::size_t size)
+        {
+            // Calculate aligned pointer
+            char *result = align(m_ptr);
+
+            // If not enough memory left in current pool, allocate a new pool
+            if (result + size > m_end)
+            {
+                // Calculate required pool size (may be bigger than BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE)
+                std::size_t pool_size = BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE;
+                if (pool_size < size)
+                    pool_size = size;
+                
+                // Allocate
+                std::size_t alloc_size = sizeof(header) + (2 * BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 2) + pool_size;     // 2 alignments required in worst case: one for header, one for actual allocation
+                char *raw_memory = allocate_raw(alloc_size);
+                    
+                // Setup new pool in allocated memory
+                char *pool = align(raw_memory);
+                header *new_header = reinterpret_cast<header *>(pool);
+                new_header->previous_begin = m_begin;
+                m_begin = raw_memory;
+                m_ptr = pool + sizeof(header);
+                m_end = raw_memory + alloc_size;
+
+                // Calculate aligned pointer again using new pool
+                result = align(m_ptr);
+            }
+
+            // Update pool and return aligned pointer
+            m_ptr = result + size;
+            return result;
+        }
+
+        char *m_begin;                                      // Start of raw memory making up current pool
+        char *m_ptr;                                        // First free byte in current pool
+        char *m_end;                                        // One past last available byte in current pool
+        char m_static_memory[BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE];    // Static raw memory
+        boost_ptree_raw_alloc_func *m_alloc_func;           // Allocator function, or 0 if default is to be used
+        boost_ptree_raw_free_func *m_free_func;             // Free function, or 0 if default is to be used
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // XML base
+
+    //! Base class for xml_node and xml_attribute implementing common functions: 
+    //! name(), name_size(), value(), value_size() and parent().
+    //! \param Ch Character type to use
+    template<class Ch = char>
+    class xml_base
+    {
+
+    public:
+        
+        ///////////////////////////////////////////////////////////////////////////
+        // Construction & destruction
+    
+        // Construct a base with empty name, value and parent
+        xml_base()
+            : m_name(0)
+            , m_value(0)
+            , m_parent(0)
+        {
+        }
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Node data access
+    
+        //! Gets name of the node. 
+        //! Interpretation of name depends on type of node.
+        //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
+        //! <br><br>
+        //! Use name_size() function to determine length of the name.
+        //! \return Name of node, or empty string if node has no name.
+        Ch *name() const
+        {
+            return m_name ? m_name : nullstr();
+        }
+
+        //! Gets size of node name, not including terminator character.
+        //! This function works correctly irrespective of whether name is or is not zero terminated.
+        //! \return Size of node name, in characters.
+        std::size_t name_size() const
+        {
+            return m_name ? m_name_size : 0;
+        }
+
+        //! Gets value of node. 
+        //! Interpretation of value depends on type of node.
+        //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
+        //! <br><br>
+        //! Use value_size() function to determine length of the value.
+        //! \return Value of node, or empty string if node has no value.
+        Ch *value() const
+        {
+            return m_value ? m_value : nullstr();
+        }
+
+        //! Gets size of node value, not including terminator character.
+        //! This function works correctly irrespective of whether value is or is not zero terminated.
+        //! \return Size of node value, in characters.
+        std::size_t value_size() const
+        {
+            return m_value ? m_value_size : 0;
+        }
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Node modification
+    
+        //! Sets name of node to a non zero-terminated string.
+        //! See \ref ownership_of_strings.
+        //! <br><br>
+        //! Note that node does not own its name or value, it only stores a pointer to it. 
+        //! It will not delete or otherwise free the pointer on destruction.
+        //! It is reponsibility of the user to properly manage lifetime of the string.
+        //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
+        //! on destruction of the document the string will be automatically freed.
+        //! <br><br>
+        //! Size of name must be specified separately, because name does not have to be zero terminated.
+        //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated).
+        //! \param n Name of node to set. Does not have to be zero terminated.
+        //! \param size Size of name, in characters. This does not include zero terminator, if one is present.
+        void name(const Ch *n, std::size_t size)
+        {
+            m_name = const_cast<Ch *>(n);
+            m_name_size = size;
+        }
+
+        //! Sets name of node to a zero-terminated string.
+        //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t).
+        //! \param n Name of node to set. Must be zero terminated.
+        void name(const Ch *n)
+        {
+            name(n, internal::measure(n));
+        }
+
+        //! Sets value of node to a non zero-terminated string.
+        //! See \ref ownership_of_strings.
+        //! <br><br>
+        //! Note that node does not own its name or value, it only stores a pointer to it. 
+        //! It will not delete or otherwise free the pointer on destruction.
+        //! It is reponsibility of the user to properly manage lifetime of the string.
+        //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
+        //! on destruction of the document the string will be automatically freed.
+        //! <br><br>
+        //! Size of value must be specified separately, because it does not have to be zero terminated.
+        //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated).
+        //! <br><br>
+        //! If an element has a child node of type node_data, it will take precedence over element value when printing.
+        //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser.
+        //! \param val value of node to set. Does not have to be zero terminated.
+        //! \param size Size of value, in characters. This does not include zero terminator, if one is present.
+        void value(const Ch *val, std::size_t size)
+        {
+            m_value = const_cast<Ch *>(val);
+            m_value_size = size;
+        }
+
+        //! Sets value of node to a zero-terminated string.
+        //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t).
+        //! \param val Vame of node to set. Must be zero terminated.
+        void value(const Ch *val)
+        {
+            this->value(val, internal::measure(val));
+        }
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Related nodes access
+    
+        //! Gets node parent.
+        //! \return Pointer to parent node, or 0 if there is no parent.
+        xml_node<Ch> *parent() const
+        {
+            return m_parent;
+        }
+
+    protected:
+
+        // Return empty string
+        static Ch *nullstr()
+        {
+            static Ch zero = Ch('\0');
+            return &zero;
+        }
+
+        Ch *m_name;                         // Name of node, or 0 if no name
+        Ch *m_value;                        // Value of node, or 0 if no value
+        std::size_t m_name_size;            // Length of node name, or undefined of no name
+        std::size_t m_value_size;           // Length of node value, or undefined if no value
+        xml_node<Ch> *m_parent;             // Pointer to parent node, or 0 if none
+
+    };
+
+    //! Class representing attribute node of XML document. 
+    //! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base).
+    //! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. 
+    //! Thus, this text must persist in memory for the lifetime of attribute.
+    //! \param Ch Character type to use.
+    template<class Ch = char>
+    class xml_attribute: public xml_base<Ch>
+    {
+
+        friend class xml_node<Ch>;
+    
+    public:
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Construction & destruction
+    
+        //! Constructs an empty attribute with the specified type. 
+        //! Consider using memory_pool of appropriate xml_document if allocating attributes manually.
+        xml_attribute()
+        {
+        }
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Related nodes access
+    
+        //! Gets document of which attribute is a child.
+        //! \return Pointer to document that contains this attribute, or 0 if there is no parent document.
+        xml_document<Ch> *document() const
+        {
+            if (xml_node<Ch> *node = this->parent())
+            {
+                while (node->parent())
+                    node = node->parent();
+                return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
+            }
+            else
+                return 0;
+        }
+
+        //! Gets previous attribute, optionally matching attribute name. 
+        //! \param n Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero
+        //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string
+        //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+        //! \return Pointer to found attribute, or 0 if not found.
+        xml_attribute<Ch> *previous_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
+        {
+            if (n)
+            {
+                if (nsize == 0)
+                    nsize = internal::measure(n);
+                for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute)
+                    if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
+                        return attribute;
+                return 0;
+            }
+            else
+                return this->m_parent ? m_prev_attribute : 0;
+        }
+
+        //! Gets next attribute, optionally matching attribute name. 
+        //! \param n Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero
+        //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string
+        //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+        //! \return Pointer to found attribute, or 0 if not found.
+        xml_attribute<Ch> *next_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
+        {
+            if (n)
+            {
+                if (nsize == 0)
+                    nsize = internal::measure(n);
+                for (xml_attribute<Ch> *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute)
+                    if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
+                        return attribute;
+                return 0;
+            }
+            else
+                return this->m_parent ? m_next_attribute : 0;
+        }
+
+    private:
+
+        xml_attribute<Ch> *m_prev_attribute;        // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero
+        xml_attribute<Ch> *m_next_attribute;        // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero
+    
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // XML node
+
+    //! Class representing a node of XML document. 
+    //! Each node may have associated name and value strings, which are available through name() and value() functions. 
+    //! Interpretation of name and value depends on type of the node.
+    //! Type of node can be determined by using type() function.
+    //! <br><br>
+    //! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. 
+    //! Thus, this text must persist in the memory for the lifetime of node.
+    //! \param Ch Character type to use.
+    template<class Ch = char>
+    class xml_node: public xml_base<Ch>
+    {
+
+    public:
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Construction & destruction
+    
+        //! Constructs an empty node with the specified type. 
+        //! Consider using memory_pool of appropriate document to allocate nodes manually.
+        //! \param t Type of node to construct.
+        xml_node(node_type t)
+            : m_type(t)
+            , m_first_node(0)
+            , m_first_attribute(0)
+        {
+        }
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Node data access
+    
+        //! Gets type of node.
+        //! \return Type of node.
+        node_type type() const
+        {
+            return m_type;
+        }
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Related nodes access
+    
+        //! Gets document of which node is a child.
+        //! \return Pointer to document that contains this node, or 0 if there is no parent document.
+        xml_document<Ch> *document() const
+        {
+            xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);
+            while (node->parent())
+                node = node->parent();
+            return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
+        }
+
+        //! Gets first child node, optionally matching node name.
+        //! \param n Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero
+        //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string
+        //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+        //! \return Pointer to found child, or 0 if not found.
+        xml_node<Ch> *first_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
+        {
+            if (n)
+            {
+                if (nsize == 0)
+                    nsize = internal::measure(n);
+                for (xml_node<Ch> *child = m_first_node; child; child = child->next_sibling())
+                    if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive))
+                        return child;
+                return 0;
+            }
+            else
+                return m_first_node;
+        }
+
+        //! Gets last child node, optionally matching node name. 
+        //! Behaviour is undefined if node has no children.
+        //! Use first_node() to test if node has children.
+        //! \param n Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero
+        //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string
+        //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+        //! \return Pointer to found child, or 0 if not found.
+        xml_node<Ch> *last_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
+        {
+            BOOST_ASSERT(m_first_node);  // Cannot query for last child if node has no children
+            if (n)
+            {
+                if (nsize == 0)
+                    nsize = internal::measure(n);
+                for (xml_node<Ch> *child = m_last_node; child; child = child->previous_sibling())
+                    if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive))
+                        return child;
+                return 0;
+            }
+            else
+                return m_last_node;
+        }
+
+        //! Gets previous sibling node, optionally matching node name. 
+        //! Behaviour is undefined if node has no parent.
+        //! Use parent() to test if node has a parent.
+        //! \param n Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero
+        //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string
+        //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+        //! \return Pointer to found sibling, or 0 if not found.
+        xml_node<Ch> *previous_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
+        {
+            BOOST_ASSERT(this->m_parent);     // Cannot query for siblings if node has no parent
+            if (n)
+            {
+                if (nsize == 0)
+                    nsize = internal::measure(n);
+                for (xml_node<Ch> *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling)
+                    if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive))
+                        return sibling;
+                return 0;
+            }
+            else
+                return m_prev_sibling;
+        }
+
+        //! Gets next sibling node, optionally matching node name. 
+        //! Behaviour is undefined if node has no parent.
+        //! Use parent() to test if node has a parent.
+        //! \param n Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero
+        //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string
+        //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+        //! \return Pointer to found sibling, or 0 if not found.
+        xml_node<Ch> *next_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
+        {
+            BOOST_ASSERT(this->m_parent);     // Cannot query for siblings if node has no parent
+            if (n)
+            {
+                if (nsize == 0)
+                    nsize = internal::measure(n);
+                for (xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling)
+                    if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive))
+                        return sibling;
+                return 0;
+            }
+            else
+                return m_next_sibling;
+        }
+
+        //! Gets first attribute of node, optionally matching attribute name.
+        //! \param n Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero
+        //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string
+        //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+        //! \return Pointer to found attribute, or 0 if not found.
+        xml_attribute<Ch> *first_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
+        {
+            if (n)
+            {
+                if (nsize == 0)
+                    nsize = internal::measure(n);
+                for (xml_attribute<Ch> *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute)
+                    if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
+                        return attribute;
+                return 0;
+            }
+            else
+                return m_first_attribute;
+        }
+
+        //! Gets last attribute of node, optionally matching attribute name.
+        //! \param n Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero
+        //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string
+        //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+        //! \return Pointer to found attribute, or 0 if not found.
+        xml_attribute<Ch> *last_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
+        {
+            if (n)
+            {
+                if (nsize == 0)
+                    nsize = internal::measure(n);
+                for (xml_attribute<Ch> *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute)
+                    if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
+                        return attribute;
+                return 0;
+            }
+            else
+                return m_first_attribute ? m_last_attribute : 0;
+        }
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Node modification
+    
+        //! Sets type of node.
+        //! \param t Type of node to set.
+        void type(node_type t)
+        {
+            m_type = t;
+        }
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Node manipulation
+
+        //! Prepends a new child node.
+        //! The prepended child becomes the first child, and all existing children are moved one position back.
+        //! \param child Node to prepend.
+        void prepend_node(xml_node<Ch> *child)
+        {
+            BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
+            if (first_node())
+            {
+                child->m_next_sibling = m_first_node;
+                m_first_node->m_prev_sibling = child;
+            }
+            else
+            {
+                child->m_next_sibling = 0;
+                m_last_node = child;
+            }
+            m_first_node = child;
+            child->m_parent = this;
+            child->m_prev_sibling = 0;
+        }
+
+        //! Appends a new child node. 
+        //! The appended child becomes the last child.
+        //! \param child Node to append.
+        void append_node(xml_node<Ch> *child)
+        {
+            BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
+            if (first_node())
+            {
+                child->m_prev_sibling = m_last_node;
+                m_last_node->m_next_sibling = child;
+            }
+            else
+            {
+                child->m_prev_sibling = 0;
+                m_first_node = child;
+            }
+            m_last_node = child;
+            child->m_parent = this;
+            child->m_next_sibling = 0;
+        }
+
+        //! Inserts a new child node at specified place inside the node. 
+        //! All children after and including the specified node are moved one position back.
+        //! \param where Place where to insert the child, or 0 to insert at the back.
+        //! \param child Node to insert.
+        void insert_node(xml_node<Ch> *where, xml_node<Ch> *child)
+        {
+            BOOST_ASSERT(!where || where->parent() == this);
+            BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
+            if (where == m_first_node)
+                prepend_node(child);
+            else if (where == 0)
+                append_node(child);
+            else
+            {
+                child->m_prev_sibling = where->m_prev_sibling;
+                child->m_next_sibling = where;
+                where->m_prev_sibling->m_next_sibling = child;
+                where->m_prev_sibling = child;
+                child->m_parent = this;
+            }
+        }
+
+        //! Removes first child node. 
+        //! If node has no children, behaviour is undefined.
+        //! Use first_node() to test if node has children.
+        void remove_first_node()
+        {
+            BOOST_ASSERT(first_node());
+            xml_node<Ch> *child = m_first_node;
+            m_first_node = child->m_next_sibling;
+            if (child->m_next_sibling)
+                child->m_next_sibling->m_prev_sibling = 0;
+            else
+                m_last_node = 0;
+            child->m_parent = 0;
+        }
+
+        //! Removes last child of the node. 
+        //! If node has no children, behaviour is undefined.
+        //! Use first_node() to test if node has children.
+        void remove_last_node()
+        {
+            BOOST_ASSERT(first_node());
+            xml_node<Ch> *child = m_last_node;
+            if (child->m_prev_sibling)
+            {
+                m_last_node = child->m_prev_sibling;
+                child->m_prev_sibling->m_next_sibling = 0;
+            }
+            else
+                m_first_node = 0;
+            child->m_parent = 0;
+        }
+
+        //! Removes specified child from the node
+        // \param where Pointer to child to be removed.
+        void remove_node(xml_node<Ch> *where)
+        {
+            BOOST_ASSERT(where && where->parent() == this);
+            BOOST_ASSERT(first_node());
+            if (where == m_first_node)
+                remove_first_node();
+            else if (where == m_last_node)
+                remove_last_node();
+            else
+            {
+                where->m_prev_sibling->m_next_sibling = where->m_next_sibling;
+                where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;
+                where->m_parent = 0;
+            }
+        }
+
+        //! Removes all child nodes (but not attributes).
+        void remove_all_nodes()
+        {
+            for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)
+                node->m_parent = 0;
+            m_first_node = 0;
+        }
+
+        //! Prepends a new attribute to the node.
+        //! \param attribute Attribute to prepend.
+        void prepend_attribute(xml_attribute<Ch> *attribute)
+        {
+            BOOST_ASSERT(attribute && !attribute->parent());
+            if (first_attribute())
+            {
+                attribute->m_next_attribute = m_first_attribute;
+                m_first_attribute->m_prev_attribute = attribute;
+            }
+            else
+            {
+                attribute->m_next_attribute = 0;
+                m_last_attribute = attribute;
+            }
+            m_first_attribute = attribute;
+            attribute->m_parent = this;
+            attribute->m_prev_attribute = 0;
+        }
+
+        //! Appends a new attribute to the node.
+        //! \param attribute Attribute to append.
+        void append_attribute(xml_attribute<Ch> *attribute)
+        {
+            BOOST_ASSERT(attribute && !attribute->parent());
+            if (first_attribute())
+            {
+                attribute->m_prev_attribute = m_last_attribute;
+                m_last_attribute->m_next_attribute = attribute;
+            }
+            else
+            {
+                attribute->m_prev_attribute = 0;
+                m_first_attribute = attribute;
+            }
+            m_last_attribute = attribute;
+            attribute->m_parent = this;
+            attribute->m_next_attribute = 0;
+        }
+
+        //! Inserts a new attribute at specified place inside the node. 
+        //! All attributes after and including the specified attribute are moved one position back.
+        //! \param where Place where to insert the attribute, or 0 to insert at the back.
+        //! \param attribute Attribute to insert.
+        void insert_attribute(xml_attribute<Ch> *where, xml_attribute<Ch> *attribute)
+        {
+            BOOST_ASSERT(!where || where->parent() == this);
+            BOOST_ASSERT(attribute && !attribute->parent());
+            if (where == m_first_attribute)
+                prepend_attribute(attribute);
+            else if (where == 0)
+                append_attribute(attribute);
+            else
+            {
+                attribute->m_prev_attribute = where->m_prev_attribute;
+                attribute->m_next_attribute = where;
+                where->m_prev_attribute->m_next_attribute = attribute;
+                where->m_prev_attribute = attribute;
+                attribute->m_parent = this;
+            }
+        }
+
+        //! Removes first attribute of the node. 
+        //! If node has no attributes, behaviour is undefined.
+        //! Use first_attribute() to test if node has attributes.
+        void remove_first_attribute()
+        {
+            BOOST_ASSERT(first_attribute());
+            xml_attribute<Ch> *attribute = m_first_attribute;
+            if (attribute->m_next_attribute)
+            {
+                attribute->m_next_attribute->m_prev_attribute = 0;
+            }
+            else
+                m_last_attribute = 0;
+            attribute->m_parent = 0;
+            m_first_attribute = attribute->m_next_attribute;
+        }
+
+        //! Removes last attribute of the node. 
+        //! If node has no attributes, behaviour is undefined.
+        //! Use first_attribute() to test if node has attributes.
+        void remove_last_attribute()
+        {
+            BOOST_ASSERT(first_attribute());
+            xml_attribute<Ch> *attribute = m_last_attribute;
+            if (attribute->m_prev_attribute)
+            {
+                attribute->m_prev_attribute->m_next_attribute = 0;
+                m_last_attribute = attribute->m_prev_attribute;
+            }
+            else
+                m_first_attribute = 0;
+            attribute->m_parent = 0;
+        }
+
+        //! Removes specified attribute from node.
+        //! \param where Pointer to attribute to be removed.
+        void remove_attribute(xml_attribute<Ch> *where)
+        {
+            BOOST_ASSERT(first_attribute() && where->parent() == this);
+            if (where == m_first_attribute)
+                remove_first_attribute();
+            else if (where == m_last_attribute)
+                remove_last_attribute();
+            else
+            {
+                where->m_prev_attribute->m_next_attribute = where->m_next_attribute;
+                where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;
+                where->m_parent = 0;
+            }
+        }
+
+        //! Removes all attributes of node.
+        void remove_all_attributes()
+        {
+            for (xml_attribute<Ch> *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute)
+                attribute->m_parent = 0;
+            m_first_attribute = 0;
+        }
+        
+    private:
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Restrictions
+
+        // No copying
+        xml_node(const xml_node &);
+        void operator =(const xml_node &);
+    
+        ///////////////////////////////////////////////////////////////////////////
+        // Data members
+    
+        // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0.
+        // This is required for maximum performance, as it allows the parser to omit initialization of 
+        // unneded/redundant values.
+        //
+        // The rules are as follows:
+        // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively
+        // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage
+        // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage
+
+        node_type m_type;                       // Type of node; always valid
+        xml_node<Ch> *m_first_node;             // Pointer to first child node, or 0 if none; always valid
+        xml_node<Ch> *m_last_node;              // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero
+        xml_attribute<Ch> *m_first_attribute;   // Pointer to first attribute of node, or 0 if none; always valid
+        xml_attribute<Ch> *m_last_attribute;    // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero
+        xml_node<Ch> *m_prev_sibling;           // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
+        xml_node<Ch> *m_next_sibling;           // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
+
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // XML document
+    
+    //! This class represents root of the DOM hierarchy. 
+    //! It is also an xml_node and a memory_pool through public inheritance.
+    //! Use parse() function to build a DOM tree from a zero-terminated XML text string.
+    //! parse() function allocates memory for nodes and attributes by using functions of xml_document, 
+    //! which are inherited from memory_pool.
+    //! To access root node of the document, use the document itself, as if it was an xml_node.
+    //! \param Ch Character type to use.
+    template<class Ch = char>
+    class xml_document: public xml_node<Ch>, public memory_pool<Ch>
+    {
+    
+    public:
+
+        //! Constructs empty XML document
+        xml_document()
+            : xml_node<Ch>(node_document)
+        {
+        }
+
+        //! Parses zero-terminated XML string according to given flags.
+        //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used.
+        //! The string must persist for the lifetime of the document.
+        //! In case of error, rapidxml::parse_error exception will be thrown.
+        //! <br><br>
+        //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning.
+        //! Make sure that data is zero-terminated.
+        //! <br><br>
+        //! Document can be parsed into multiple times. 
+        //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool.
+        //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser.
+        template<int Flags>
+        void parse(Ch *text)
+        {
+            BOOST_ASSERT(text);
+            
+            // Remove current contents
+            this->remove_all_nodes();
+            this->remove_all_attributes();
+            
+            // Parse BOM, if any
+            parse_bom<Flags>(text);
+            
+            // Parse children
+            while (1)
+            {
+                // Skip whitespace before node
+                skip<whitespace_pred, Flags>(text);
+                if (*text == 0)
+                    break;
+
+                // Parse and append new child
+                if (*text == Ch('<'))
+                {
+                    ++text;     // Skip '<'
+                    if (xml_node<Ch> *node = parse_node<Flags>(text))
+                        this->append_node(node);
+                }
+                else
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected <", text);
+            }
+
+        }
+
+        //! Clears the document by deleting all nodes and clearing the memory pool.
+        //! All nodes owned by document pool are destroyed.
+        void clear()
+        {
+            this->remove_all_nodes();
+            this->remove_all_attributes();
+            memory_pool<Ch>::clear();
+        }
+        
+    private:
+
+        ///////////////////////////////////////////////////////////////////////
+        // Internal character utility functions
+        
+        // Detect whitespace character
+        struct whitespace_pred
+        {
+            static unsigned char test(Ch ch)
+            {
+                return internal::lookup_tables<0>::lookup_whitespace[internal::get_index(ch)];
+            }
+        };
+
+        // Detect node name character
+        struct node_name_pred
+        {
+            static unsigned char test(Ch ch)
+            {
+                return internal::lookup_tables<0>::lookup_node_name[internal::get_index(ch)];
+            }
+        };
+
+        // Detect attribute name character
+        struct attribute_name_pred
+        {
+            static unsigned char test(Ch ch)
+            {
+                return internal::lookup_tables<0>::lookup_attribute_name[internal::get_index(ch)];
+            }
+        };
+
+        // Detect text character (PCDATA)
+        struct text_pred
+        {
+            static unsigned char test(Ch ch)
+            {
+                return internal::lookup_tables<0>::lookup_text[internal::get_index(ch)];
+            }
+        };
+
+        // Detect text character (PCDATA) that does not require processing
+        struct text_pure_no_ws_pred
+        {
+            static unsigned char test(Ch ch)
+            {
+                return internal::lookup_tables<0>::lookup_text_pure_no_ws[internal::get_index(ch)];
+            }
+        };
+
+        // Detect text character (PCDATA) that does not require processing
+        struct text_pure_with_ws_pred
+        {
+            static unsigned char test(Ch ch)
+            {
+                return internal::lookup_tables<0>::lookup_text_pure_with_ws[internal::get_index(ch)];
+            }
+        };
+
+        // Detect attribute value character
+        template<Ch Quote>
+        struct attribute_value_pred
+        {
+            static unsigned char test(Ch ch)
+            {
+                if (Quote == Ch('\''))
+                    return internal::lookup_tables<0>::lookup_attribute_data_1[internal::get_index(ch)];
+                if (Quote == Ch('\"'))
+                    return internal::lookup_tables<0>::lookup_attribute_data_2[internal::get_index(ch)];
+                return 0;       // Should never be executed, to avoid warnings on Comeau
+            }
+        };
+
+        // Detect attribute value character
+        template<Ch Quote>
+        struct attribute_value_pure_pred
+        {
+            static unsigned char test(Ch ch)
+            {
+                if (Quote == Ch('\''))
+                    return internal::lookup_tables<0>::lookup_attribute_data_1_pure[internal::get_index(ch)];
+                if (Quote == Ch('\"'))
+                    return internal::lookup_tables<0>::lookup_attribute_data_2_pure[internal::get_index(ch)];
+                return 0;       // Should never be executed, to avoid warnings on Comeau
+            }
+        };
+
+        // Insert coded character, using UTF8 or 8-bit ASCII
+        template<int Flags>
+        static void insert_coded_character(Ch *&text, unsigned long code)
+        {
+            if (Flags & parse_no_utf8)
+            {
+                // Insert 8-bit ASCII character
+                // Todo: possibly verify that code is less than 256 and use replacement char otherwise?
+                text[0] = static_cast<unsigned char>(code);
+                text += 1;
+            }
+            else
+            {
+                // Insert UTF8 sequence
+                if (code < 0x80)    // 1 byte sequence
+                {
+                    text[0] = static_cast<unsigned char>(code);
+                    text += 1;
+                }
+                else if (code < 0x800)  // 2 byte sequence
+                {
+                    text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+                    text[0] = static_cast<unsigned char>(code | 0xC0);
+                    text += 2;
+                }
+                else if (code < 0x10000)    // 3 byte sequence
+                {
+                    text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+                    text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+                    text[0] = static_cast<unsigned char>(code | 0xE0);
+                    text += 3;
+                }
+                else if (code < 0x110000)   // 4 byte sequence
+                {
+                    text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+                    text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+                    text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+                    text[0] = static_cast<unsigned char>(code | 0xF0);
+                    text += 4;
+                }
+                else    // Invalid, only codes up to 0x10FFFF are allowed in Unicode
+                {
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);
+                }
+            }
+        }
+
+        // Skip characters until predicate evaluates to true
+        template<class StopPred, int Flags>
+        static void skip(Ch *&text)
+        {
+            Ch *tmp = text;
+            while (StopPred::test(*tmp))
+                ++tmp;
+            text = tmp;
+        }
+
+        // Skip characters until predicate evaluates to true while doing the following:
+        // - replacing XML character entity references with proper characters (&apos; &amp; &quot; &lt; &gt; &#...;)
+        // - condensing whitespace sequences to single space character
+        template<class StopPred, class StopPredPure, int Flags>
+        static Ch *skip_and_expand_character_refs(Ch *&text)
+        {
+            // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip
+            if (Flags & parse_no_entity_translation && 
+                !(Flags & parse_normalize_whitespace) &&
+                !(Flags & parse_trim_whitespace))
+            {
+                skip<StopPred, Flags>(text);
+                return text;
+            }
+            
+            // Use simple skip until first modification is detected
+            skip<StopPredPure, Flags>(text);
+
+            // Use translation skip
+            Ch *src = text;
+            Ch *dest = src;
+            while (StopPred::test(*src))
+            {
+                // If entity translation is enabled    
+                if (!(Flags & parse_no_entity_translation))
+                {
+                    // Test if replacement is needed
+                    if (src[0] == Ch('&'))
+                    {
+                        switch (src[1])
+                        {
+
+                        // &amp; &apos;
+                        case Ch('a'): 
+                            if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';'))
+                            {
+                                *dest = Ch('&');
+                                ++dest;
+                                src += 5;
+                                continue;
+                            }
+                            if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';'))
+                            {
+                                *dest = Ch('\'');
+                                ++dest;
+                                src += 6;
+                                continue;
+                            }
+                            break;
+
+                        // &quot;
+                        case Ch('q'): 
+                            if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';'))
+                            {
+                                *dest = Ch('"');
+                                ++dest;
+                                src += 6;
+                                continue;
+                            }
+                            break;
+
+                        // &gt;
+                        case Ch('g'): 
+                            if (src[2] == Ch('t') && src[3] == Ch(';'))
+                            {
+                                *dest = Ch('>');
+                                ++dest;
+                                src += 4;
+                                continue;
+                            }
+                            break;
+
+                        // &lt;
+                        case Ch('l'): 
+                            if (src[2] == Ch('t') && src[3] == Ch(';'))
+                            {
+                                *dest = Ch('<');
+                                ++dest;
+                                src += 4;
+                                continue;
+                            }
+                            break;
+
+                        // &#...; - assumes ASCII
+                        case Ch('#'): 
+                            if (src[2] == Ch('x'))
+                            {
+                                unsigned long code = 0;
+                                src += 3;   // Skip &#x
+                                while (1)
+                                {
+                                    unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+                                    if (digit == 0xFF)
+                                        break;
+                                    code = code * 16 + digit;
+                                    ++src;
+                                }
+                                insert_coded_character<Flags>(dest, code);    // Put character in output
+                            }
+                            else
+                            {
+                                unsigned long code = 0;
+                                src += 2;   // Skip &#
+                                while (1)
+                                {
+                                    unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+                                    if (digit == 0xFF)
+                                        break;
+                                    code = code * 10 + digit;
+                                    ++src;
+                                }
+                                insert_coded_character<Flags>(dest, code);    // Put character in output
+                            }
+                            if (*src == Ch(';'))
+                                ++src;
+                            else
+                                BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ;", src);
+                            continue;
+
+                        // Something else
+                        default:
+                            // Ignore, just copy '&' verbatim
+                            break;
+
+                        }
+                    }
+                }
+                
+                // If whitespace condensing is enabled
+                if (Flags & parse_normalize_whitespace)
+                {
+                    // Test if condensing is needed                 
+                    if (whitespace_pred::test(*src))
+                    {
+                        *dest = Ch(' '); ++dest;    // Put single space in dest
+                        ++src;                      // Skip first whitespace char
+                        // Skip remaining whitespace chars
+                        while (whitespace_pred::test(*src))
+                            ++src;
+                        continue;
+                    }
+                }
+
+                // No replacement, only copy character
+                *dest++ = *src++;
+
+            }
+
+            // Return new end
+            text = src;
+            return dest;
+
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        // Internal parsing functions
+        
+        // Parse UTF-8 BOM, if any
+        template<int Flags>
+        void parse_bom(char *&text)
+        {
+            if (static_cast<unsigned char>(text[0]) == 0xEF && 
+                static_cast<unsigned char>(text[1]) == 0xBB && 
+                static_cast<unsigned char>(text[2]) == 0xBF)
+            {
+                text += 3;
+            }
+        }
+        
+        // Parse UTF-16/32 BOM, if any
+        template<int Flags>
+        void parse_bom(wchar_t *&text)
+        {
+            const wchar_t bom = 0xFEFF;
+            if (text[0] == bom)
+            {
+                ++text;
+            }
+        }
+
+        // Parse XML declaration (<?xml...)
+        template<int Flags>
+        xml_node<Ch> *parse_xml_declaration(Ch *&text)
+        {
+            // If parsing of declaration is disabled
+            if (!(Flags & parse_declaration_node))
+            {
+                // Skip until end of declaration
+                while (text[0] != Ch('?') || text[1] != Ch('>'))
+                {
+                    if (!text[0])
+                        BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                    ++text;
+                }
+                text += 2;    // Skip '?>'
+                return 0;
+            }
+
+            // Create declaration
+            xml_node<Ch> *declaration = this->allocate_node(node_declaration);
+
+            // Skip whitespace before attributes or ?>
+            skip<whitespace_pred, Flags>(text);
+
+            // Parse declaration attributes
+            parse_node_attributes<Flags>(text, declaration);
+            
+            // Skip ?>
+            if (text[0] != Ch('?') || text[1] != Ch('>'))
+                BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ?>", text);
+            text += 2;
+            
+            return declaration;
+        }
+
+        // Parse XML comment (<!--...)
+        template<int Flags>
+        xml_node<Ch> *parse_comment(Ch *&text)
+        {
+            // If parsing of comments is disabled
+            if (!(Flags & parse_comment_nodes))
+            {
+                // Skip until end of comment
+                while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
+                {
+                    if (!text[0])
+                        BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                    ++text;
+                }
+                text += 3;     // Skip '-->'
+                return 0;      // Do not produce comment node
+            }
+
+            // Remember value start
+            Ch *val = text;
+
+            // Skip until end of comment
+            while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
+            {
+                if (!text[0])
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                ++text;
+            }
+
+            // Create comment node
+            xml_node<Ch> *comment = this->allocate_node(node_comment);
+            comment->value(val, text - val);
+            
+            // Place zero terminator after comment value
+            if (!(Flags & parse_no_string_terminators))
+                *text = Ch('\0');
+            
+            text += 3;     // Skip '-->'
+            return comment;
+        }
+
+        // Parse DOCTYPE
+        template<int Flags>
+        xml_node<Ch> *parse_doctype(Ch *&text)
+        {
+            // Remember value start
+            Ch *val = text;
+
+            // Skip to >
+            while (*text != Ch('>'))
+            {
+                // Determine character type
+                switch (*text)
+                {
+                
+                // If '[' encountered, scan for matching ending ']' using naive algorithm with depth
+                // This works for all W3C test files except for 2 most wicked
+                case Ch('['):
+                {
+                    ++text;     // Skip '['
+                    int depth = 1;
+                    while (depth > 0)
+                    {
+                        switch (*text)
+                        {
+                            case Ch('['): ++depth; break;
+                            case Ch(']'): --depth; break;
+                            case 0: BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                            default: break;
+                        }
+                        ++text;
+                    }
+                    break;
+                }
+                
+                // Error on end of text
+                case Ch('\0'):
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                
+                // Other character, skip it
+                default:
+                    ++text;
+
+                }
+            }
+            
+            // If DOCTYPE nodes enabled
+            if (Flags & parse_doctype_node)
+            {
+                // Create a new doctype node
+                xml_node<Ch> *doctype = this->allocate_node(node_doctype);
+                doctype->value(val, text - val);
+                
+                // Place zero terminator after value
+                if (!(Flags & parse_no_string_terminators))
+                    *text = Ch('\0');
+
+                text += 1;      // skip '>'
+                return doctype;
+            }
+            else
+            {
+                text += 1;      // skip '>'
+                return 0;
+            }
+
+        }
+
+        // Parse PI
+        template<int Flags>
+        xml_node<Ch> *parse_pi(Ch *&text)
+        {
+            // If creation of PI nodes is enabled
+            if (Flags & parse_pi_nodes)
+            {
+                // Create pi node
+                xml_node<Ch> *pi = this->allocate_node(node_pi);
+
+                // Extract PI target name
+                Ch *n = text;
+                skip<node_name_pred, Flags>(text);
+                if (text == n)
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected PI target", text);
+                pi->name(n, text - n);
+                
+                // Skip whitespace between pi target and pi
+                skip<whitespace_pred, Flags>(text);
+
+                // Remember start of pi
+                Ch *val = text;
+                
+                // Skip to '?>'
+                while (text[0] != Ch('?') || text[1] != Ch('>'))
+                {
+                    if (*text == Ch('\0'))
+                        BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                    ++text;
+                }
+
+                // Set pi value (verbatim, no entity expansion or whitespace normalization)
+                pi->value(val, text - val);
+
+                // Place zero terminator after name and value
+                if (!(Flags & parse_no_string_terminators))
+                {
+                    pi->name()[pi->name_size()] = Ch('\0');
+                    pi->value()[pi->value_size()] = Ch('\0');
+                }
+                
+                text += 2;                          // Skip '?>'
+                return pi;
+            }
+            else
+            {
+                // Skip to '?>'
+                while (text[0] != Ch('?') || text[1] != Ch('>'))
+                {
+                    if (*text == Ch('\0'))
+                        BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                    ++text;
+                }
+                text += 2;    // Skip '?>'
+                return 0;
+            }
+        }
+
+        // Parse and append data
+        // Return character that ends data.
+        // This is necessary because this character might have been overwritten by a terminating 0
+        template<int Flags>
+        Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start)
+        {
+            // Backup to contents start if whitespace trimming is disabled
+            if (!(Flags & parse_trim_whitespace))
+                text = contents_start;     
+            
+            // Skip until end of data
+            Ch *val = text, *end;
+            if (Flags & parse_normalize_whitespace)
+                end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred, Flags>(text);   
+            else
+                end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred, Flags>(text);
+
+            // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after >
+            if (Flags & parse_trim_whitespace)
+            {
+                if (Flags & parse_normalize_whitespace)
+                {
+                    // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end
+                    if (*(end - 1) == Ch(' '))
+                        --end;
+                }
+                else
+                {
+                    // Backup until non-whitespace character is found
+                    while (whitespace_pred::test(*(end - 1)))
+                        --end;
+                }
+            }
+            
+            // If characters are still left between end and value (this test is only necessary if normalization is enabled)
+            // Create new data node
+            if (!(Flags & parse_no_data_nodes))
+            {
+                xml_node<Ch> *data = this->allocate_node(node_data);
+                data->value(val, end - val);
+                node->append_node(data);
+            }
+
+            // Add data to parent node if no data exists yet
+            if (!(Flags & parse_no_element_values)) 
+                if (*node->value() == Ch('\0'))
+                    node->value(val, end - val);
+
+            // Place zero terminator after value
+            if (!(Flags & parse_no_string_terminators))
+            {
+                Ch ch = *text;
+                *end = Ch('\0');
+                return ch;      // Return character that ends data; this is required because zero terminator overwritten it
+            }
+
+            // Return character that ends data
+            return *text;
+        }
+
+        // Parse CDATA
+        template<int Flags>
+        xml_node<Ch> *parse_cdata(Ch *&text)
+        {
+            // If CDATA is disabled
+            if (Flags & parse_no_data_nodes)
+            {
+                // Skip until end of cdata
+                while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
+                {
+                    if (!text[0])
+                        BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                    ++text;
+                }
+                text += 3;      // Skip ]]>
+                return 0;       // Do not produce CDATA node
+            }
+
+            // Skip until end of cdata
+            Ch *val = text;
+            while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
+            {
+                if (!text[0])
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                ++text;
+            }
+
+            // Create new cdata node
+            xml_node<Ch> *cdata = this->allocate_node(node_cdata);
+            cdata->value(val, text - val);
+
+            // Place zero terminator after value
+            if (!(Flags & parse_no_string_terminators))
+                *text = Ch('\0');
+
+            text += 3;      // Skip ]]>
+            return cdata;
+        }
+        
+        // Parse element node
+        template<int Flags>
+        xml_node<Ch> *parse_element(Ch *&text)
+        {
+            // Create element node
+            xml_node<Ch> *element = this->allocate_node(node_element);
+
+            // Extract element name
+            Ch *n = text;
+            skip<node_name_pred, Flags>(text);
+            if (text == n)
+                BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected element name", text);
+            element->name(n, text - n);
+            
+            // Skip whitespace between element name and attributes or >
+            skip<whitespace_pred, Flags>(text);
+
+            // Parse attributes, if any
+            parse_node_attributes<Flags>(text, element);
+
+            // Determine ending type
+            if (*text == Ch('>'))
+            {
+                ++text;
+                parse_node_contents<Flags>(text, element);
+            }
+            else if (*text == Ch('/'))
+            {
+                ++text;
+                if (*text != Ch('>'))
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
+                ++text;
+            }
+            else
+                BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
+
+            // Place zero terminator after name
+            if (!(Flags & parse_no_string_terminators))
+                element->name()[element->name_size()] = Ch('\0');
+
+            // Return parsed element
+            return element;
+        }
+
+        // Determine node type, and parse it
+        template<int Flags>
+        xml_node<Ch> *parse_node(Ch *&text)
+        {
+            // Parse proper node type
+            switch (text[0])
+            {
+
+            // <...
+            default: 
+                // Parse and append element node
+                return parse_element<Flags>(text);
+
+            // <?...
+            case Ch('?'): 
+                ++text;     // Skip ?
+                if ((text[0] == Ch('x') || text[0] == Ch('X')) &&
+                    (text[1] == Ch('m') || text[1] == Ch('M')) && 
+                    (text[2] == Ch('l') || text[2] == Ch('L')) &&
+                    whitespace_pred::test(text[3]))
+                {
+                    // '<?xml ' - xml declaration
+                    text += 4;      // Skip 'xml '
+                    return parse_xml_declaration<Flags>(text);
+                }
+                else
+                {
+                    // Parse PI
+                    return parse_pi<Flags>(text);
+                }
+            
+            // <!...
+            case Ch('!'): 
+
+                // Parse proper subset of <! node
+                switch (text[1])    
+                {
+                
+                // <!-
+                case Ch('-'):
+                    if (text[2] == Ch('-'))
+                    {
+                        // '<!--' - xml comment
+                        text += 3;     // Skip '!--'
+                        return parse_comment<Flags>(text);
+                    }
+                    break;
+
+                // <![
+                case Ch('['):
+                    if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A') && 
+                        text[5] == Ch('T') && text[6] == Ch('A') && text[7] == Ch('['))
+                    {
+                        // '<![CDATA[' - cdata
+                        text += 8;     // Skip '![CDATA['
+                        return parse_cdata<Flags>(text);
+                    }
+                    break;
+
+                // <!D
+                case Ch('D'):
+                    if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T') && 
+                        text[5] == Ch('Y') && text[6] == Ch('P') && text[7] == Ch('E') && 
+                        whitespace_pred::test(text[8]))
+                    {
+                        // '<!DOCTYPE ' - doctype
+                        text += 9;      // skip '!DOCTYPE '
+                        return parse_doctype<Flags>(text);
+                    }
+                    break;
+
+                default: break;
+
+                }   // switch
+
+                // Attempt to skip other, unrecognized node types starting with <!
+                ++text;     // Skip !
+                while (*text != Ch('>'))
+                {
+                    if (*text == 0)
+                        BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                    ++text;
+                }
+                ++text;     // Skip '>'
+                return 0;   // No node recognized
+
+            }
+        }
+
+        // Parse contents of the node - children, data etc.
+        template<int Flags>
+        void parse_node_contents(Ch *&text, xml_node<Ch> *node)
+        {
+            // For all children and text
+            while (1)
+            {
+                // Skip whitespace between > and node contents
+                Ch *contents_start = text;      // Store start of node contents before whitespace is skipped
+                if (Flags & parse_trim_whitespace)
+                    skip<whitespace_pred, Flags>(text);
+                Ch next_char = *text;
+
+            // After data nodes, instead of continuing the loop, control jumps here.
+            // This is because zero termination inside parse_and_append_data() function
+            // would wreak havoc with the above code.
+            // Also, skipping whitespace after data nodes is unnecessary.
+            after_data_node:    
+                
+                // Determine what comes next: node closing, child node, data node, or 0?
+                switch (next_char)
+                {
+                
+                // Node closing or child node
+                case Ch('<'):
+                    if (text[1] == Ch('/'))
+                    {
+                        // Node closing
+                        text += 2;      // Skip '</'
+                        if (Flags & parse_validate_closing_tags)
+                        {
+                            // Skip and validate closing tag name
+                            Ch *closing_name = text;
+                            skip<node_name_pred, Flags>(text);
+                            if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true))
+                                BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid closing tag name", text);
+                        }
+                        else
+                        {
+                            // No validation, just skip name
+                            skip<node_name_pred, Flags>(text);
+                        }
+                        // Skip remaining whitespace after node name
+                        skip<whitespace_pred, Flags>(text);
+                        if (*text != Ch('>'))
+                            BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
+                        ++text;     // Skip '>'
+                        return;     // Node closed, finished parsing contents
+                    }
+                    else
+                    {
+                        // Child node
+                        ++text;     // Skip '<'
+                        if (xml_node<Ch> *child = parse_node<Flags>(text))
+                            node->append_node(child);
+                    }
+                    break;
+
+                // End of data - error
+                case Ch('\0'):
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+
+                // Data node
+                default:
+                    next_char = parse_and_append_data<Flags>(node, text, contents_start);
+                    goto after_data_node;   // Bypass regular processing after data nodes
+
+                }
+            }
+        }
+        
+        // Parse XML attributes of the node
+        template<int Flags>
+        void parse_node_attributes(Ch *&text, xml_node<Ch> *node)
+        {
+            // For all attributes 
+            while (attribute_name_pred::test(*text))
+            {
+                // Extract attribute name
+                Ch *n = text;
+                ++text;     // Skip first character of attribute name
+                skip<attribute_name_pred, Flags>(text);
+                if (text == n)
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected attribute name", n);
+
+                // Create new attribute
+                xml_attribute<Ch> *attribute = this->allocate_attribute();
+                attribute->name(n, text - n);
+                node->append_attribute(attribute);
+
+                // Skip whitespace after attribute name
+                skip<whitespace_pred, Flags>(text);
+
+                // Skip =
+                if (*text != Ch('='))
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected =", text);
+                ++text;
+
+                // Add terminating zero after name
+                if (!(Flags & parse_no_string_terminators))
+                    attribute->name()[attribute->name_size()] = 0;
+
+                // Skip whitespace after =
+                skip<whitespace_pred, Flags>(text);
+
+                // Skip quote and remember if it was ' or "
+                Ch quote = *text;
+                if (quote != Ch('\'') && quote != Ch('"'))
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+                ++text;
+
+                // Extract attribute value and expand char refs in it
+                Ch *val = text, *end;
+                const int AttFlags = Flags & ~parse_normalize_whitespace;   // No whitespace normalization in attributes
+                if (quote == Ch('\''))
+                    end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>, attribute_value_pure_pred<Ch('\'')>, AttFlags>(text);
+                else
+                    end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>, attribute_value_pure_pred<Ch('"')>, AttFlags>(text);
+                
+                // Set attribute value
+                attribute->value(val, end - val);
+                
+                // Make sure that end quote is present
+                if (*text != quote)
+                    BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+                ++text;     // Skip quote
+
+                // Add terminating zero after value
+                if (!(Flags & parse_no_string_terminators))
+                    attribute->value()[attribute->value_size()] = 0;
+
+                // Skip whitespace after attribute value
+                skip<whitespace_pred, Flags>(text);
+            }
+        }
+
+    };
+
+    //! \cond internal
+    namespace internal
+    {
+
+        // Whitespace (space \n \r \t)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,  // 0
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 1
+             1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 2
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 3
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 4
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 5
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 6
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 7
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 8
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 9
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // A
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // B
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // C
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // D
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // E
+             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   // F
+        };
+
+        // Node name (anything but space \n \r \t / > ? \0)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_node_name[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  0,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Text (i.e. PCDATA) (anything but < \0)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_text[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled 
+        // (anything but < \0 &)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled
+        // (anything but < \0 & space \n \r \t)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  0,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Attribute name (anything but space \n \r \t / < > = ? ! \0)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  0,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Attribute data with single quote (anything but ' \0)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Attribute data with single quote that does not require processing (anything but ' \0 &)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Attribute data with double quote (anything but " \0)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Attribute data with double quote that does not require processing (anything but " \0 &)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
+             1,  1,  0,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 3
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
+             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
+        };
+
+        // Digits (dec and hex, 255 denotes end of numeric character reference)
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_digits[256] = 
+        {
+          // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // 0
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // 1
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // 2
+             0,  1,  2,  3,  4,  5,  6,  7,  8,  9,255,255,255,255,255,255,  // 3
+           255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255,  // 4
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // 5
+           255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255,  // 6
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // 7
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // 8
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // 9
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // A
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // B
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // C
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // D
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  // E
+           255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255   // F
+        };
+    
+        // Upper case conversion
+        template<int Dummy>
+        const unsigned char lookup_tables<Dummy>::lookup_upcase[256] = 
+        {
+          // 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  A   B   C   D   E   F
+           0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,   // 0
+           16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,   // 1
+           32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,   // 2
+           48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,   // 3
+           64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,   // 4
+           80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,   // 5
+           96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,   // 6
+           80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123,124,125,126,127,  // 7
+           128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,  // 8
+           144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,  // 9
+           160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,  // A
+           176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,  // B
+           192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,  // C
+           208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,  // D
+           224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,  // E
+           240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255   // F
+        };
+    }
+    //! \endcond
+
+}}}}
+
+// Undefine internal macros
+#undef BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR
+
+// On MSVC, restore warnings state
+#ifdef _MSC_VER
+    #pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/boost/property_tree/detail/xml_parser_error.hpp b/include/boost/property_tree/detail/xml_parser_error.hpp
new file mode 100644
index 0000000..c79835c
--- /dev/null
+++ b/include/boost/property_tree/detail/xml_parser_error.hpp
@@ -0,0 +1,33 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED
+
+#include <boost/property_tree/detail/file_parser_error.hpp>
+#include <string>
+
+namespace boost { namespace property_tree { namespace xml_parser
+{
+
+    //! Xml parser error
+    class xml_parser_error: public file_parser_error
+    {
+    public:
+        xml_parser_error(const std::string &msg,
+                         const std::string &file,
+                         unsigned long l):
+            file_parser_error(msg, file, l)
+        {
+        }
+    };
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/xml_parser_flags.hpp b/include/boost/property_tree/detail/xml_parser_flags.hpp
new file mode 100644
index 0000000..9340fe2
--- /dev/null
+++ b/include/boost/property_tree/detail/xml_parser_flags.hpp
@@ -0,0 +1,31 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED
+
+namespace boost { namespace property_tree { namespace xml_parser
+{
+
+    /// Text elements should be put in separate keys,
+    /// not concatenated in parent data.
+    static const int no_concat_text  = 0x1;
+    /// Comments should be omitted.
+    static const int no_comments     = 0x2;
+    /// Whitespace should be collapsed and trimmed.
+    static const int trim_whitespace = 0x4;
+
+    inline bool validate_flags(int flags)
+    {
+        return (flags & ~(no_concat_text | no_comments | trim_whitespace)) == 0;
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp b/include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp
new file mode 100644
index 0000000..9c04219
--- /dev/null
+++ b/include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp
@@ -0,0 +1,144 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2007 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/detail/xml_parser_error.hpp>
+#include <boost/property_tree/detail/xml_parser_flags.hpp>
+#include <boost/property_tree/detail/xml_parser_utils.hpp>
+#include <boost/property_tree/detail/rapidxml.hpp>
+#include <vector>
+
+namespace boost { namespace property_tree { namespace xml_parser
+{
+
+    template<class Ptree, class Ch>
+    void read_xml_node(detail::rapidxml::xml_node<Ch> *node,
+                       Ptree &pt, int flags)
+    {
+        using namespace detail::rapidxml;
+        switch (node->type())
+        {
+            // Element nodes
+            case node_element: 
+            {
+                // Create node
+                Ptree &pt_node = pt.push_back(std::make_pair(node->name(),
+                                                             Ptree()))->second;
+
+                // Copy attributes
+                if (node->first_attribute())
+                {
+                    Ptree &pt_attr_root = pt_node.push_back(
+                        std::make_pair(xmlattr<typename Ptree::key_type>(), Ptree()))->second;
+                    for (xml_attribute<Ch> *attr = node->first_attribute();
+                         attr; attr = attr->next_attribute())
+                    {
+                        Ptree &pt_attr = pt_attr_root.push_back(
+                            std::make_pair(attr->name(), Ptree()))->second;
+                        pt_attr.data() = typename Ptree::key_type(attr->value(), attr->value_size());
+                    }
+                }
+
+                // Copy children
+                for (xml_node<Ch> *child = node->first_node();
+                     child; child = child->next_sibling())
+                    read_xml_node(child, pt_node, flags);
+            }
+            break;
+
+            // Data nodes
+            case node_data:
+            case node_cdata:
+            {
+                if (flags & no_concat_text)
+                    pt.push_back(std::make_pair(xmltext<typename Ptree::key_type>(),
+                                                Ptree(node->value())));
+                else
+                    pt.data() += typename Ptree::key_type(node->value(), node->value_size());
+            }
+            break;
+
+            // Comment nodes
+            case node_comment:
+            {
+                if (!(flags & no_comments))
+                    pt.push_back(std::make_pair(xmlcomment<typename Ptree::key_type>(),
+                                    Ptree(typename Ptree::key_type(node->value(), node->value_size()))));
+            }
+            break;
+
+            default:
+                // Skip other node types
+                break;
+        }
+    }
+
+    template<class Ptree>
+    void read_xml_internal(std::basic_istream<
+                               typename Ptree::key_type::value_type> &stream,
+                           Ptree &pt,
+                           int flags,
+                           const std::string &filename)
+    {
+        typedef typename Ptree::key_type::value_type Ch;
+        using namespace detail::rapidxml;
+
+        // Load data into vector
+        stream.unsetf(std::ios::skipws);
+        std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
+                          std::istreambuf_iterator<Ch>());
+        if (!stream.good())
+            BOOST_PROPERTY_TREE_THROW(
+                xml_parser_error("read error", filename, 0));
+        v.push_back(0); // zero-terminate
+
+        try {
+            // Parse using appropriate flags
+            const int f_tws = parse_normalize_whitespace
+                            | parse_trim_whitespace;
+            const int f_c = parse_comment_nodes;
+            // Some compilers don't like the bitwise or in the template arg.
+            const int f_tws_c = parse_normalize_whitespace
+                              | parse_trim_whitespace
+                              | parse_comment_nodes;
+            xml_document<Ch> doc;
+            if (flags & no_comments) {
+                if (flags & trim_whitespace)
+                    doc.BOOST_NESTED_TEMPLATE parse<f_tws>(&v.front());
+                else
+                    doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front());
+            } else {
+                if (flags & trim_whitespace)
+                    doc.BOOST_NESTED_TEMPLATE parse<f_tws_c>(&v.front());
+                else
+                    doc.BOOST_NESTED_TEMPLATE parse<f_c>(&v.front());
+            }
+
+            // Create ptree from nodes
+            Ptree local;
+            for (xml_node<Ch> *child = doc.first_node();
+                 child; child = child->next_sibling())
+                read_xml_node(child, local, flags);
+
+            // Swap local and result ptrees
+            pt.swap(local);
+        } catch (parse_error &e) {
+            long line = static_cast<long>(
+                std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1);
+            BOOST_PROPERTY_TREE_THROW(
+                xml_parser_error(e.what(), filename, line));  
+        }
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/xml_parser_utils.hpp b/include/boost/property_tree/detail/xml_parser_utils.hpp
new file mode 100644
index 0000000..fbbde01
--- /dev/null
+++ b/include/boost/property_tree/detail/xml_parser_utils.hpp
@@ -0,0 +1,139 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED
+
+#include <boost/property_tree/detail/ptree_utils.hpp>
+#include <boost/property_tree/detail/xml_parser_error.hpp>
+#include <boost/property_tree/detail/xml_parser_writer_settings.hpp>
+#include <string>
+#include <algorithm>
+#include <locale>
+
+namespace boost { namespace property_tree { namespace xml_parser
+{
+
+    template<class Str>
+    Str condense(const Str &s)
+    {
+        typedef typename Str::value_type Ch;
+        Str r;
+        std::locale loc;
+        bool space = false;
+        typename Str::const_iterator end = s.end();
+        for (typename Str::const_iterator it = s.begin();
+             it != end; ++it)
+        {
+            if (isspace(*it, loc) || *it == Ch('\n'))
+            {
+                if (!space)
+                    r += Ch(' '), space = true;
+            }
+            else
+                r += *it, space = false;
+        }
+        return r;
+    }
+
+
+    template<class Str>
+    Str encode_char_entities(const Str &s)
+    {
+        // Don't do anything for empty strings.
+        if(s.empty()) return s;
+
+        typedef typename Str::value_type Ch;
+
+        Str r;
+        // To properly round-trip spaces and not uglify the XML beyond
+        // recognition, we have to encode them IF the text contains only spaces.
+        Str sp(1, Ch(' '));
+        if(s.find_first_not_of(sp) == Str::npos) {
+            // The first will suffice.
+            r = detail::widen<Str>("&#32;");
+            r += Str(s.size() - 1, Ch(' '));
+        } else {
+            typename Str::const_iterator end = s.end();
+            for (typename Str::const_iterator it = s.begin(); it != end; ++it)
+            {
+                switch (*it)
+                {
+                    case Ch('<'): r += detail::widen<Str>("&lt;"); break;
+                    case Ch('>'): r += detail::widen<Str>("&gt;"); break;
+                    case Ch('&'): r += detail::widen<Str>("&amp;"); break;
+                    case Ch('"'): r += detail::widen<Str>("&quot;"); break;
+                    case Ch('\''): r += detail::widen<Str>("&apos;"); break;
+                    default: r += *it; break;
+                }
+            }
+        }
+        return r;
+    }
+
+    template<class Str>
+    Str decode_char_entities(const Str &s)
+    {
+        typedef typename Str::value_type Ch;
+        Str r;
+        typename Str::const_iterator end = s.end();
+        for (typename Str::const_iterator it = s.begin(); it != end; ++it)
+        {
+            if (*it == Ch('&'))
+            {
+                typename Str::const_iterator semicolon = std::find(it + 1, end, Ch(';'));
+                if (semicolon == end)
+                    BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0));
+                Str ent(it + 1, semicolon);
+                if (ent == detail::widen<Str>("lt")) r += Ch('<');
+                else if (ent == detail::widen<Str>("gt")) r += Ch('>');
+                else if (ent == detail::widen<Str>("amp")) r += Ch('&');
+                else if (ent == detail::widen<Str>("quot")) r += Ch('"');
+                else if (ent == detail::widen<Str>("apos")) r += Ch('\'');
+                else
+                    BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0));
+                it = semicolon;
+            }
+            else
+                r += *it;
+        }
+        return r;
+    }
+
+    template<class Str>
+    const Str &xmldecl()
+    {
+        static Str s = detail::widen<Str>("<?xml>");
+        return s;
+    }
+
+    template<class Str>
+    const Str &xmlattr()
+    {
+        static Str s = detail::widen<Str>("<xmlattr>");
+        return s;
+    }
+
+    template<class Str>
+    const Str &xmlcomment()
+    {
+        static Str s = detail::widen<Str>("<xmlcomment>");
+        return s;
+    }
+
+    template<class Str>
+    const Str &xmltext()
+    {
+        static Str s = detail::widen<Str>("<xmltext>");
+        return s;
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/xml_parser_write.hpp b/include/boost/property_tree/detail/xml_parser_write.hpp
new file mode 100644
index 0000000..0af2265
--- /dev/null
+++ b/include/boost/property_tree/detail/xml_parser_write.hpp
@@ -0,0 +1,195 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2013 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/detail/xml_parser_utils.hpp>
+#include <string>
+#include <ostream>
+#include <iomanip>
+
+namespace boost { namespace property_tree { namespace xml_parser
+{
+    template<class Str>
+    void write_xml_indent(std::basic_ostream<typename Str::value_type> &stream,
+          int indent,
+          const xml_writer_settings<Str> & settings
+          )
+    {
+        stream << std::basic_string<typename Str::value_type>(indent * settings.indent_count, settings.indent_char);
+    }
+
+    template<class Str>
+    void write_xml_comment(std::basic_ostream<typename Str::value_type> &stream,
+                           const Str &s,
+                           int indent,
+                           bool separate_line,
+                           const xml_writer_settings<Str> & settings
+                           )
+    {
+        typedef typename Str::value_type Ch;
+        if (separate_line)
+            write_xml_indent(stream,indent,settings);
+        stream << Ch('<') << Ch('!') << Ch('-') << Ch('-');
+        stream << s;
+        stream << Ch('-') << Ch('-') << Ch('>');
+        if (separate_line)
+            stream << Ch('\n');
+    }
+
+    template<class Str>
+    void write_xml_text(std::basic_ostream<typename Str::value_type> &stream,
+                        const Str &s,
+                        int indent, 
+                        bool separate_line,
+                        const xml_writer_settings<Str> & settings
+                        )
+    {
+        typedef typename Str::value_type Ch;
+        if (separate_line)
+            write_xml_indent(stream,indent,settings);
+        stream << encode_char_entities(s);
+        if (separate_line)
+            stream << Ch('\n');
+    }
+
+    template<class Ptree>
+    void write_xml_element(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
+                           const typename Ptree::key_type &key,
+                           const Ptree &pt,
+                           int indent,
+                           const xml_writer_settings<typename Ptree::key_type> & settings)
+    {
+        typedef typename Ptree::key_type::value_type Ch;
+        typedef typename Ptree::key_type Str;
+        typedef typename Ptree::const_iterator It;
+
+        bool want_pretty = settings.indent_count > 0;
+        // Find if elements present
+        bool has_elements = false;
+        bool has_attrs_only = pt.data().empty();
+        for (It it = pt.begin(), end = pt.end(); it != end; ++it)
+        {
+            if (it->first != xmlattr<Str>() )
+            {
+                has_attrs_only = false;
+                if (it->first != xmltext<Str>())
+                {
+                    has_elements = true;
+                    break;
+                }
+            }
+        }
+
+        // Write element
+        if (pt.data().empty() && pt.empty())    // Empty key
+        {
+            if (indent >= 0)
+            {
+                write_xml_indent(stream,indent,settings);
+                stream << Ch('<') << key << 
+                          Ch('/') << Ch('>');
+                if (want_pretty)
+                    stream << Ch('\n');
+            }
+        }
+        else    // Nonempty key
+        {
+            // Write opening tag, attributes and data
+            if (indent >= 0)
+            {
+                // Write opening brace and key
+                write_xml_indent(stream,indent,settings);
+                stream << Ch('<') << key;
+
+                // Write attributes
+                if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Str>()))
+                    for (It it = attribs.get().begin(); it != attribs.get().end(); ++it)
+                        stream << Ch(' ') << it->first << Ch('=')
+                               << Ch('"')
+                               << encode_char_entities(
+                                    it->second.template get_value<Str>())
+                               << Ch('"');
+
+                if ( has_attrs_only )
+                {
+                    // Write closing brace
+                    stream << Ch('/') << Ch('>');
+                    if (want_pretty)
+                        stream << Ch('\n');
+                }
+                else
+                {
+                    // Write closing brace
+                    stream << Ch('>');
+
+                    // Break line if needed and if we want pretty-printing
+                    if (has_elements && want_pretty)
+                        stream << Ch('\n');
+                }
+            }
+
+            // Write data text, if present
+            if (!pt.data().empty())
+                write_xml_text(stream,
+                    pt.template get_value<Str>(),
+                    indent + 1, has_elements && want_pretty, settings);
+
+            // Write elements, comments and texts
+            for (It it = pt.begin(); it != pt.end(); ++it)
+            {
+                if (it->first == xmlattr<Str>())
+                    continue;
+                else if (it->first == xmlcomment<Str>())
+                    write_xml_comment(stream,
+                        it->second.template get_value<Str>(),
+                        indent + 1, want_pretty, settings);
+                else if (it->first == xmltext<Str>())
+                    write_xml_text(stream,
+                        it->second.template get_value<Str>(),
+                        indent + 1, has_elements && want_pretty, settings);
+                else
+                    write_xml_element(stream, it->first, it->second,
+                        indent + 1, settings);
+            }
+
+            // Write closing tag
+            if (indent >= 0 && !has_attrs_only)
+            {
+                if (has_elements)
+                    write_xml_indent(stream,indent,settings);
+                stream << Ch('<') << Ch('/') << key << Ch('>');
+                if (want_pretty)
+                    stream << Ch('\n');
+            }
+
+        }
+    }
+
+    template<class Ptree>
+    void write_xml_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream, 
+                            const Ptree &pt,
+                            const std::string &filename,
+                            const xml_writer_settings<typename Ptree::key_type> & settings)
+    {
+        typedef typename Ptree::key_type Str;
+        stream  << detail::widen<Str>("<?xml version=\"1.0\" encoding=\"")
+                << settings.encoding
+                << detail::widen<Str>("\"?>\n");
+        write_xml_element(stream, Str(), pt, -1, settings);
+        if (!stream)
+            BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename, 0));
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/detail/xml_parser_writer_settings.hpp b/include/boost/property_tree/detail/xml_parser_writer_settings.hpp
new file mode 100644
index 0000000..5fb79f3
--- /dev/null
+++ b/include/boost/property_tree/detail/xml_parser_writer_settings.hpp
@@ -0,0 +1,64 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2007 Marcin Kalicinski
+// Copyright (C) 2007 Alexey Baskakov
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED
+
+#include <string>
+#include <boost/property_tree/detail/ptree_utils.hpp>
+
+namespace boost { namespace property_tree { namespace xml_parser
+{
+
+    // Naively convert narrow string to another character type
+    template<class Str>
+    Str widen(const char *text)
+    {
+        typedef typename Str::value_type Ch;
+        Str result;
+        while (*text)
+        {
+            result += Ch(*text);
+            ++text;
+        }
+        return result;
+    }
+
+    //! Xml writer settings. The default settings lead to no pretty printing.
+    template<class Str>
+    class xml_writer_settings
+    {
+        typedef typename Str::value_type Ch;
+    public:
+        xml_writer_settings(Ch inchar = Ch(' '),
+                typename Str::size_type incount = 0,
+                const Str &enc = widen<Str>("utf-8"))
+            : indent_char(inchar)
+            , indent_count(incount)
+            , encoding(enc)
+        {
+        }
+
+        Ch indent_char;
+        typename Str::size_type indent_count;
+        Str encoding;
+    };
+
+    template <class Str>
+    xml_writer_settings<Str> xml_writer_make_settings(typename Str::value_type indent_char = (typename Str::value_type)(' '),
+        typename Str::size_type indent_count = 0,
+        const Str &encoding = widen<Str>("utf-8"))
+    {
+        return xml_writer_settings<Str>(indent_char, indent_count, encoding);
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/exceptions.hpp b/include/boost/property_tree/exceptions.hpp
new file mode 100644
index 0000000..b35b27f
--- /dev/null
+++ b/include/boost/property_tree/exceptions.hpp
@@ -0,0 +1,86 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_EXCEPTIONS_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_EXCEPTIONS_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+
+#include <boost/any.hpp>
+#include <string>
+#include <stdexcept>
+
+namespace boost { namespace property_tree
+{
+
+    /// Base class for all property tree errors. Derives from
+    /// @c std::runtime_error. Call member function @c what to get human
+    /// readable message associated with the error.
+    class ptree_error : public std::runtime_error
+    {
+    public:
+        /// Instantiate a ptree_error instance with the given message.
+        /// @param what The message to associate with this error.
+        ptree_error(const std::string &what);
+
+        ~ptree_error() throw();
+    };
+
+
+    /// Error indicating that translation from given value to the property tree
+    /// data_type (or vice versa) failed. Derives from ptree_error.
+    class ptree_bad_data : public ptree_error
+    {
+    public:
+        /// Instantiate a ptree_bad_data instance with the given message and
+        /// data.
+        /// @param what The message to associate with this error.
+        /// @param data The value associated with this error that was the source
+        ///             of the translation failure.
+        template<class T> ptree_bad_data(const std::string &what,
+                                         const T &data);
+
+        ~ptree_bad_data() throw();
+
+        /// Retrieve the data associated with this error. This is the source
+        /// value that failed to be translated. You need to explicitly
+        /// specify its type.
+        template<class T> T data() const;
+    private:
+        boost::any m_data;
+    };
+
+
+    /// Error indicating that specified path does not exist. Derives from
+    /// ptree_error.
+    class ptree_bad_path : public ptree_error
+    {
+    public:
+        /// Instantiate a ptree_bad_path with the given message and path data.
+        /// @param what The message to associate with this error.
+        /// @param path The path that could not be found in the property_tree.
+        template<class T> ptree_bad_path(const std::string &what,
+                                         const T &path);
+
+        ~ptree_bad_path() throw();
+
+        /// Retrieve the invalid path. You need to explicitly specify the
+        /// type of path.
+        template<class T> T path() const;
+    private:
+        boost::any m_path;
+    };
+
+}}
+
+#include <boost/property_tree/detail/exception_implementation.hpp>
+
+#endif
diff --git a/include/boost/property_tree/id_translator.hpp b/include/boost/property_tree/id_translator.hpp
new file mode 100644
index 0000000..02fdf44
--- /dev/null
+++ b/include/boost/property_tree/id_translator.hpp
@@ -0,0 +1,51 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_ID_TRANSLATOR_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_ID_TRANSLATOR_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+
+#include <boost/optional.hpp>
+#include <string>
+
+namespace boost { namespace property_tree
+{
+
+    /// Simple implementation of the Translator concept. It does no translation.
+    template <typename T>
+    struct id_translator
+    {
+        typedef T internal_type;
+        typedef T external_type;
+
+        boost::optional<T> get_value(const T &v) { return v; }
+        boost::optional<T> put_value(const T &v) { return v; }
+    };
+
+    // This is the default translator whenever you get two equal types.
+    template <typename T>
+    struct translator_between<T, T>
+    {
+        typedef id_translator<T> type;
+    };
+
+    // A more specific specialization for std::basic_string. Otherwise,
+    // stream_translator's specialization wins.
+    template <typename Ch, typename Traits, typename Alloc>
+    struct translator_between< std::basic_string<Ch, Traits, Alloc>,
+                               std::basic_string<Ch, Traits, Alloc> >
+    {
+        typedef id_translator< std::basic_string<Ch, Traits, Alloc> > type;
+    };
+
+}}
+
+#endif
diff --git a/include/boost/property_tree/info_parser.hpp b/include/boost/property_tree/info_parser.hpp
new file mode 100644
index 0000000..683ddad
--- /dev/null
+++ b/include/boost/property_tree/info_parser.hpp
@@ -0,0 +1,151 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_INFO_PARSER_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_INFO_PARSER_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/detail/info_parser_error.hpp>
+#include <boost/property_tree/detail/info_parser_writer_settings.hpp>
+#include <boost/property_tree/detail/info_parser_read.hpp>
+#include <boost/property_tree/detail/info_parser_write.hpp>
+#include <istream>
+
+namespace boost { namespace property_tree { namespace info_parser
+{
+
+    /**
+     * Read INFO from a the given stream and translate it to a property tree.
+     * @note Replaces the existing contents. Strong exception guarantee.
+     * @throw info_parser_error If the stream cannot be read, doesn't contain
+     *                          valid INFO, or a conversion fails.
+     */
+    template<class Ptree, class Ch>
+    void read_info(std::basic_istream<Ch> &stream, Ptree &pt)
+    {
+        Ptree local;
+        read_info_internal(stream, local, std::string(), 0);
+        pt.swap(local);
+    }
+
+    /**
+     * Read INFO from a the given stream and translate it to a property tree.
+     * @note Replaces the existing contents. Strong exception guarantee.
+     * @param default_ptree If parsing fails, pt is set to a copy of this tree.
+     */
+    template<class Ptree, class Ch>
+    void read_info(std::basic_istream<Ch> &stream, Ptree &pt,
+                   const Ptree &default_ptree)
+    {
+        try {
+            read_info(stream, pt);
+        } catch(file_parser_error &) {
+            pt = default_ptree;
+        }
+    }
+
+    /**
+     * Read INFO from a the given file and translate it to a property tree. The
+     * tree's key type must be a string type, i.e. it must have a nested
+     * value_type typedef that is a valid parameter for basic_ifstream.
+     * @note Replaces the existing contents. Strong exception guarantee.
+     * @throw info_parser_error If the file cannot be read, doesn't contain
+     *                          valid INFO, or a conversion fails.
+     */
+    template<class Ptree>
+    void read_info(const std::string &filename, Ptree &pt,
+                   const std::locale &loc = std::locale())
+    {
+        std::basic_ifstream<typename Ptree::key_type::value_type>
+            stream(filename.c_str());
+        if (!stream) {
+            BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                "cannot open file for reading", filename, 0));
+        }
+        stream.imbue(loc);
+        Ptree local;
+        read_info_internal(stream, local, filename, 0);
+        pt.swap(local);
+    }
+
+    /**
+     * Read INFO from a the given file and translate it to a property tree. The
+     * tree's key type must be a string type, i.e. it must have a nested
+     * value_type typedef that is a valid parameter for basic_ifstream.
+     * @note Replaces the existing contents. Strong exception guarantee.
+     * @param default_ptree If parsing fails, pt is set to a copy of this tree.
+     */
+    template<class Ptree>
+    void read_info(const std::string &filename,
+                   Ptree &pt,
+                   const Ptree &default_ptree,
+                   const std::locale &loc = std::locale())
+    {
+        try {
+            read_info(filename, pt, loc);
+        } catch(file_parser_error &) {
+            pt = default_ptree;
+        }
+    }
+
+    /**
+     * Writes a tree to the stream in INFO format.
+     * @throw info_parser_error If the stream cannot be written to, or a
+     *                          conversion fails.
+     * @param settings The settings to use when writing the INFO data.
+     */
+    template<class Ptree, class Ch>
+    void write_info(std::basic_ostream<Ch> &stream,
+                    const Ptree &pt,
+                    const info_writer_settings<Ch> &settings =
+                        info_writer_settings<Ch>())
+    {
+        write_info_internal(stream, pt, std::string(), settings);
+    }
+
+    /**
+     * Writes a tree to the file in INFO format. The tree's key type must be a
+     * string type, i.e. it must have a nested value_type typedef that is a
+     * valid parameter for basic_ofstream.
+     * @throw info_parser_error If the file cannot be written to, or a
+     *                          conversion fails.
+     * @param settings The settings to use when writing the INFO data.
+     */
+    template<class Ptree>
+    void write_info(const std::string &filename,
+                    const Ptree &pt,
+                    const std::locale &loc = std::locale(),
+                    const info_writer_settings<
+                        typename Ptree::key_type::value_type
+                    > &settings =
+                        info_writer_make_settings<
+                            typename Ptree::key_type::value_type>())
+    {
+        std::basic_ofstream<typename Ptree::key_type::value_type>
+            stream(filename.c_str());
+        if (!stream) {
+            BOOST_PROPERTY_TREE_THROW(info_parser_error(
+                "cannot open file for writing", filename, 0));
+        }
+        stream.imbue(loc);
+        write_info_internal(stream, pt, filename, settings);
+    }
+
+} } }
+
+namespace boost { namespace property_tree
+{
+    using info_parser::info_parser_error;
+    using info_parser::read_info;
+    using info_parser::write_info;
+    using info_parser::info_writer_settings;
+    using info_parser::info_writer_make_settings;
+} }
+
+#endif
diff --git a/include/boost/property_tree/ini_parser.hpp b/include/boost/property_tree/ini_parser.hpp
new file mode 100644
index 0000000..50d3c97
--- /dev/null
+++ b/include/boost/property_tree/ini_parser.hpp
@@ -0,0 +1,334 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_INI_PARSER_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_INI_PARSER_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/detail/ptree_utils.hpp>
+#include <boost/property_tree/detail/file_parser_error.hpp>
+#include <fstream>
+#include <string>
+#include <sstream>
+#include <stdexcept>
+#include <locale>
+
+namespace boost { namespace property_tree { namespace ini_parser
+{
+
+    /**
+     * Determines whether the @c flags are valid for use with the ini_parser.
+     * @param flags value to check for validity as flags to ini_parser.
+     * @return true if the flags are valid, false otherwise.
+     */
+    inline bool validate_flags(int flags)
+    {
+        return flags == 0;
+    }
+
+    /** Indicates an error parsing INI formatted data. */
+    class ini_parser_error: public file_parser_error
+    {
+    public:
+        /**
+         * Construct an @c ini_parser_error
+         * @param message Message describing the parser error.
+         * @param filename The name of the file being parsed containing the
+         *                 error.
+         * @param line The line in the given file where an error was
+         *             encountered.
+         */
+        ini_parser_error(const std::string &message,
+                         const std::string &filename,
+                         unsigned long line)
+            : file_parser_error(message, filename, line)
+        {
+        }
+    };
+
+    /**
+     * Read INI from a the given stream and translate it to a property tree.
+     * @note Clears existing contents of property tree. In case of error
+     *       the property tree is not modified.
+     * @throw ini_parser_error If a format violation is found.
+     * @param stream Stream from which to read in the property tree.
+     * @param[out] pt The property tree to populate.
+     */
+    template<class Ptree>
+    void read_ini(std::basic_istream<
+                    typename Ptree::key_type::value_type> &stream,
+                  Ptree &pt)
+    {
+        typedef typename Ptree::key_type::value_type Ch;
+        typedef std::basic_string<Ch> Str;
+        const Ch semicolon = stream.widen(';');
+        const Ch hash = stream.widen('#');
+        const Ch lbracket = stream.widen('[');
+        const Ch rbracket = stream.widen(']');
+
+        Ptree local;
+        unsigned long line_no = 0;
+        Ptree *section = 0;
+        Str line;
+
+        // For all lines
+        while (stream.good())
+        {
+
+            // Get line from stream
+            ++line_no;
+            std::getline(stream, line);
+            if (!stream.good() && !stream.eof())
+                BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                    "read error", "", line_no));
+
+            // If line is non-empty
+            line = property_tree::detail::trim(line, stream.getloc());
+            if (!line.empty())
+            {
+                // Comment, section or key?
+                if (line[0] == semicolon || line[0] == hash)
+                {
+                    // Ignore comments
+                }
+                else if (line[0] == lbracket)
+                {
+                    // If the previous section was empty, drop it again.
+                    if (section && section->empty())
+                        local.pop_back();
+                    typename Str::size_type end = line.find(rbracket);
+                    if (end == Str::npos)
+                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                            "unmatched '['", "", line_no));
+                    Str key = property_tree::detail::trim(
+                        line.substr(1, end - 1), stream.getloc());
+                    if (local.find(key) != local.not_found())
+                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                            "duplicate section name", "", line_no));
+                    section = &local.push_back(
+                        std::make_pair(key, Ptree()))->second;
+                }
+                else
+                {
+                    Ptree &container = section ? *section : local;
+                    typename Str::size_type eqpos = line.find(Ch('='));
+                    if (eqpos == Str::npos)
+                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                            "'=' character not found in line", "", line_no));
+                    if (eqpos == 0)
+                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                            "key expected", "", line_no));
+                    Str key = property_tree::detail::trim(
+                        line.substr(0, eqpos), stream.getloc());
+                    Str data = property_tree::detail::trim(
+                        line.substr(eqpos + 1, Str::npos), stream.getloc());
+                    if (container.find(key) != container.not_found())
+                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                            "duplicate key name", "", line_no));
+                    container.push_back(std::make_pair(key, Ptree(data)));
+                }
+            }
+        }
+        // If the last section was empty, drop it again.
+        if (section && section->empty())
+            local.pop_back();
+
+        // Swap local ptree with result ptree
+        pt.swap(local);
+
+    }
+
+    /**
+     * Read INI from a the given file and translate it to a property tree.
+     * @note Clears existing contents of property tree.  In case of error the
+     *       property tree unmodified.
+     * @throw ini_parser_error In case of error deserializing the property tree.
+     * @param filename Name of file from which to read in the property tree.
+     * @param[out] pt The property tree to populate.
+     * @param loc The locale to use when reading in the file contents.
+     */
+    template<class Ptree>
+    void read_ini(const std::string &filename, 
+                  Ptree &pt,
+                  const std::locale &loc = std::locale())
+    {
+        std::basic_ifstream<typename Ptree::key_type::value_type>
+            stream(filename.c_str());
+        if (!stream)
+            BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                "cannot open file", filename, 0));
+        stream.imbue(loc);
+        try {
+            read_ini(stream, pt);
+        }
+        catch (ini_parser_error &e) {
+            BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                e.message(), filename, e.line()));
+        }
+    }
+
+    namespace detail
+    {
+        template<class Ptree>
+        void check_dupes(const Ptree &pt)
+        {
+            if(pt.size() <= 1)
+                return;
+            const typename Ptree::key_type *lastkey = 0;
+            typename Ptree::const_assoc_iterator it = pt.ordered_begin(),
+                                                 end = pt.not_found();
+            lastkey = &it->first;
+            for(++it; it != end; ++it) {
+                if(*lastkey == it->first)
+                    BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                        "duplicate key", "", 0));
+                lastkey = &it->first;
+            }
+        }
+
+        template <typename Ptree>
+        void write_keys(std::basic_ostream<
+                                      typename Ptree::key_type::value_type
+                                  > &stream,
+                                  const Ptree& pt,
+                                  bool throw_on_children)
+        {
+            typedef typename Ptree::key_type::value_type Ch;
+            for (typename Ptree::const_iterator it = pt.begin(), end = pt.end();
+                 it != end; ++it)
+            {
+                if (!it->second.empty()) {
+                    if (throw_on_children) {
+                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                            "ptree is too deep", "", 0));
+                    }
+                    continue;
+                }
+                stream << it->first << Ch('=')
+                    << it->second.template get_value<
+                        std::basic_string<Ch> >()
+                    << Ch('\n');
+            }
+        }
+
+        template <typename Ptree>
+        void write_top_level_keys(std::basic_ostream<
+                                      typename Ptree::key_type::value_type
+                                  > &stream,
+                                  const Ptree& pt)
+        {
+            write_keys(stream, pt, false);
+        }
+
+        template <typename Ptree>
+        void write_sections(std::basic_ostream<
+                                typename Ptree::key_type::value_type
+                            > &stream,
+                            const Ptree& pt)
+        {
+            typedef typename Ptree::key_type::value_type Ch;
+            for (typename Ptree::const_iterator it = pt.begin(), end = pt.end();
+                 it != end; ++it)
+            {
+                if (!it->second.empty()) {
+                    check_dupes(it->second);
+                    if (!it->second.data().empty())
+                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                            "mixed data and children", "", 0));
+                    stream << Ch('[') << it->first << Ch(']') << Ch('\n');
+                    write_keys(stream, it->second, true);
+                }
+            }
+        }
+    }
+
+    /**
+     * Translates the property tree to INI and writes it the given output
+     * stream.
+     * @pre @e pt cannot have data in its root.
+     * @pre @e pt cannot have keys both data and children.
+     * @pre @e pt cannot be deeper than two levels.
+     * @pre There cannot be duplicate keys on any given level of @e pt.
+     * @throw ini_parser_error In case of error translating the property tree to
+     *                         INI or writing to the output stream.
+     * @param stream The stream to which to write the INI representation of the 
+     *               property tree.
+     * @param pt The property tree to tranlsate to INI and output.
+     * @param flags The flags to use when writing the INI file.
+     *              No flags are currently supported.
+     */
+    template<class Ptree>
+    void write_ini(std::basic_ostream<
+                       typename Ptree::key_type::value_type
+                   > &stream,
+                   const Ptree &pt,
+                   int flags = 0)
+    {
+        BOOST_ASSERT(validate_flags(flags));
+        (void)flags;
+
+        if (!pt.data().empty())
+            BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                "ptree has data on root", "", 0));
+        detail::check_dupes(pt);
+
+        detail::write_top_level_keys(stream, pt);
+        detail::write_sections(stream, pt);
+    }
+
+    /**
+     * Translates the property tree to INI and writes it the given file.
+     * @pre @e pt cannot have data in its root.
+     * @pre @e pt cannot have keys both data and children.
+     * @pre @e pt cannot be deeper than two levels.
+     * @pre There cannot be duplicate keys on any given level of @e pt.
+     * @throw info_parser_error In case of error translating the property tree
+     *                          to INI or writing to the file.
+     * @param filename The name of the file to which to write the INI
+     *                 representation of the property tree.
+     * @param pt The property tree to tranlsate to INI and output.
+     * @param flags The flags to use when writing the INI file.
+     *              The following flags are supported:
+     * @li @c skip_ini_validity_check -- Skip check if ptree is a valid ini. The
+     *     validity check covers the preconditions but takes <tt>O(n log n)</tt>
+     *     time.
+     * @param loc The locale to use when writing the file.
+     */
+    template<class Ptree>
+    void write_ini(const std::string &filename,
+                   const Ptree &pt,
+                   int flags = 0,
+                   const std::locale &loc = std::locale())
+    {
+        std::basic_ofstream<typename Ptree::key_type::value_type>
+            stream(filename.c_str());
+        if (!stream)
+            BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                "cannot open file", filename, 0));
+        stream.imbue(loc);
+        try {
+            write_ini(stream, pt, flags);
+        }
+        catch (ini_parser_error &e) {
+            BOOST_PROPERTY_TREE_THROW(ini_parser_error(
+                e.message(), filename, e.line()));
+        }
+    }
+
+} } }
+
+namespace boost { namespace property_tree
+{
+    using ini_parser::ini_parser_error;
+    using ini_parser::read_ini;
+    using ini_parser::write_ini;
+} }
+
+#endif
diff --git a/include/boost/property_tree/json_parser.hpp b/include/boost/property_tree/json_parser.hpp
new file mode 100644
index 0000000..62fd89f
--- /dev/null
+++ b/include/boost/property_tree/json_parser.hpp
@@ -0,0 +1,140 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2015 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser/error.hpp>
+#include <boost/property_tree/json_parser/detail/read.hpp>
+#include <boost/property_tree/json_parser/detail/write.hpp>
+
+#include <fstream>
+#include <string>
+#include <locale>
+
+namespace boost { namespace property_tree { namespace json_parser
+{
+
+    /**
+     * Read JSON from a the given stream and translate it to a property tree.
+     * @note Clears existing contents of property tree.  In case of error the
+     *       property tree unmodified.
+     * @note Items of JSON arrays are translated into ptree keys with empty
+     *       names. Members of objects are translated into named keys.
+     * @note JSON data can be a string, a numeric value, or one of literals
+     *       "null", "true" and "false". During parse, any of the above is
+     *       copied verbatim into ptree data string.
+     * @throw json_parser_error In case of error deserializing the property
+     *                          tree.
+     * @param stream Stream from which to read in the property tree.
+     * @param[out] pt The property tree to populate.
+     */
+    template<class Ptree>
+    void read_json(std::basic_istream<
+                       typename Ptree::key_type::value_type
+                   > &stream,
+                   Ptree &pt)
+    {
+        detail::read_json_internal(stream, pt, std::string());
+    }
+
+    /**
+     * Read JSON from a the given file and translate it to a property tree.
+     * @note Clears existing contents of property tree.  In case of error the
+     *       property tree unmodified.
+     * @note Items of JSON arrays are translated into ptree keys with empty
+     *       names. Members of objects are translated into named keys.
+     * @note JSON data can be a string, a numeric value, or one of literals
+     *       "null", "true" and "false". During parse, any of the above is
+     *       copied verbatim into ptree data string.
+     * @throw json_parser_error In case of error deserializing the property
+     *                          tree.
+     * @param filename Name of file from which to read in the property tree.
+     * @param[out] pt The property tree to populate.
+     * @param loc The locale to use when reading in the file contents.
+     */
+    template<class Ptree>
+    void read_json(const std::string &filename,
+                   Ptree &pt,
+                   const std::locale &loc = std::locale())
+    {
+        std::basic_ifstream<typename Ptree::key_type::value_type>
+            stream(filename.c_str());
+        if (!stream)
+            BOOST_PROPERTY_TREE_THROW(json_parser_error(
+                "cannot open file", filename, 0));
+        stream.imbue(loc);
+        detail::read_json_internal(stream, pt, filename);
+    }
+
+    /**
+     * Translates the property tree to JSON and writes it the given output
+     * stream.
+     * @note Any property tree key containing only unnamed subkeys will be
+     *       rendered as JSON arrays.
+     * @pre @e pt cannot contain keys that have both subkeys and non-empty data.
+     * @throw json_parser_error In case of error translating the property tree
+     *                          to JSON or writing to the output stream.
+     * @param stream The stream to which to write the JSON representation of the
+     *               property tree.
+     * @param pt The property tree to tranlsate to JSON and output.
+     * @param pretty Whether to pretty-print. Defaults to true for backward
+     *               compatibility.
+     */
+    template<class Ptree>
+    void write_json(std::basic_ostream<
+                        typename Ptree::key_type::value_type
+                    > &stream,
+                    const Ptree &pt,
+                    bool pretty = true)
+    {
+        write_json_internal(stream, pt, std::string(), pretty);
+    }
+
+    /**
+     * Translates the property tree to JSON and writes it the given file.
+     * @note Any property tree key containing only unnamed subkeys will be
+     *       rendered as JSON arrays.
+     * @pre @e pt cannot contain keys that have both subkeys and non-empty data.
+     * @throw json_parser_error In case of error translating the property tree
+     *                          to JSON or writing to the file.
+     * @param filename The name of the file to which to write the JSON
+     *                 representation of the property tree.
+     * @param pt The property tree to translate to JSON and output.
+     * @param loc The locale to use when writing out to the output file.
+     * @param pretty Whether to pretty-print. Defaults to true and last place
+     *               for backward compatibility.
+     */
+    template<class Ptree>
+    void write_json(const std::string &filename,
+                    const Ptree &pt,
+                    const std::locale &loc = std::locale(),
+                    bool pretty = true)
+    {
+        std::basic_ofstream<typename Ptree::key_type::value_type>
+            stream(filename.c_str());
+        if (!stream)
+            BOOST_PROPERTY_TREE_THROW(json_parser_error(
+                "cannot open file", filename, 0));
+        stream.imbue(loc);
+        write_json_internal(stream, pt, filename, pretty);
+    }
+
+} } }
+
+namespace boost { namespace property_tree
+{
+    using json_parser::read_json;
+    using json_parser::write_json;
+    using json_parser::json_parser_error;
+} }
+
+#endif
diff --git a/include/boost/property_tree/json_parser/detail/narrow_encoding.hpp b/include/boost/property_tree/json_parser/detail/narrow_encoding.hpp
new file mode 100644
index 0000000..4e25e68
--- /dev/null
+++ b/include/boost/property_tree/json_parser/detail/narrow_encoding.hpp
@@ -0,0 +1,168 @@
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_NARROW_ENCODING_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_NARROW_ENCODING_HPP
+
+#include <boost/assert.hpp>
+#include <boost/range/iterator_range_core.hpp>
+
+#include <utility>
+
+namespace boost { namespace property_tree {
+    namespace json_parser { namespace detail
+{
+
+    struct external_ascii_superset_encoding
+    {
+        typedef char external_char;
+
+        bool is_nl(char c) const { return c == '\n'; }
+        bool is_ws(char c) const {
+            return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+        }
+
+        bool is_minus(char c) const { return c == '-'; }
+        bool is_plusminus(char c) const { return c == '+' || c == '-'; }
+        bool is_dot(char c) const { return c == '.'; }
+        bool is_eE(char c) const { return c == 'e' || c == 'E'; }
+        bool is_0(char c) const { return c == '0'; }
+        bool is_digit(char c) const { return c >= '0' && c <= '9'; }
+        bool is_digit0(char c) const { return c >= '1' && c <= '9'; }
+
+        bool is_quote(char c) const { return c == '"'; }
+        bool is_backslash(char c) const { return c == '\\'; }
+        bool is_slash(char c) const { return c == '/'; }
+
+        bool is_comma(char c) const { return c == ','; }
+        bool is_open_bracket(char c) const { return c == '['; }
+        bool is_close_bracket(char c) const { return c == ']'; }
+        bool is_colon(char c) const { return c == ':'; }
+        bool is_open_brace(char c) const { return c == '{'; }
+        bool is_close_brace(char c) const { return c == '}'; }
+
+        bool is_a(char c) const { return c == 'a'; }
+        bool is_b(char c) const { return c == 'b'; }
+        bool is_e(char c) const { return c == 'e'; }
+        bool is_f(char c) const { return c == 'f'; }
+        bool is_l(char c) const { return c == 'l'; }
+        bool is_n(char c) const { return c == 'n'; }
+        bool is_r(char c) const { return c == 'r'; }
+        bool is_s(char c) const { return c == 's'; }
+        bool is_t(char c) const { return c == 't'; }
+        bool is_u(char c) const { return c == 'u'; }
+
+        int decode_hexdigit(char c) {
+            if (c >= '0' && c <= '9') return c - '0';
+            if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+            if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+            return -1;
+        }
+    };
+
+    struct utf8_utf8_encoding : external_ascii_superset_encoding
+    {
+        typedef char internal_char;
+
+        template <typename Iterator>
+        boost::iterator_range<Iterator>
+        to_internal(Iterator first, Iterator last) const {
+            return boost::make_iterator_range(first, last);
+        }
+
+        char to_internal_trivial(char c) const {
+            BOOST_ASSERT(static_cast<unsigned char>(c) <= 0x7f);
+            return c;
+        }
+
+        template <typename Iterator, typename Sentinel,
+                  typename EncodingErrorFn>
+        void skip_codepoint(Iterator& cur, Sentinel end,
+                            EncodingErrorFn error_fn) const {
+            transcode_codepoint(cur, end, DoNothing(), error_fn);
+        }
+
+        template <typename Iterator, typename Sentinel, typename TranscodedFn,
+                  typename EncodingErrorFn>
+        void transcode_codepoint(Iterator& cur, Sentinel end,
+                TranscodedFn transcoded_fn, EncodingErrorFn error_fn) const {
+            unsigned char c = *cur;
+            ++cur;
+            if (c <= 0x7f) {
+                // Solo byte, filter out disallowed codepoints.
+                if (c < 0x20) {
+                    error_fn();
+                }
+                transcoded_fn(c);
+                return;
+            }
+            int trailing = trail_table(c);
+            if (trailing == -1) {
+                // Standalone trailing byte or overly long sequence.
+                error_fn();
+            }
+            transcoded_fn(c);
+            for (int i = 0; i < trailing; ++i) {
+                if (cur == end || !is_trail(*cur)) {
+                    error_fn();
+                }
+                transcoded_fn(*cur);
+                ++cur;
+            }
+        }
+
+        template <typename TranscodedFn>
+        void feed_codepoint(unsigned codepoint,
+                            TranscodedFn transcoded_fn) const {
+            if (codepoint <= 0x7f) {
+                transcoded_fn(static_cast<char>(codepoint));
+            } else if (codepoint <= 0x7ff) {
+                transcoded_fn(static_cast<char>(0xc0 | (codepoint >> 6)));
+                transcoded_fn(trail(codepoint));
+            } else if (codepoint <= 0xffff) {
+                transcoded_fn(static_cast<char>(0xe0 | (codepoint >> 12)));
+                transcoded_fn(trail(codepoint >> 6));
+                transcoded_fn(trail(codepoint));
+            } else if (codepoint <= 0x10ffff) {
+                transcoded_fn(static_cast<char>(0xf0 | (codepoint >> 18)));
+                transcoded_fn(trail(codepoint >> 12));
+                transcoded_fn(trail(codepoint >> 6));
+                transcoded_fn(trail(codepoint));
+            }
+        }
+
+        template <typename Iterator, typename Sentinel>
+        void skip_introduction(Iterator& cur, Sentinel end) const {
+            if (cur != end && static_cast<unsigned char>(*cur) == 0xef) {
+                if (++cur == end) return;
+                if (++cur == end) return;
+                if (++cur == end) return;
+            }
+        }
+
+    private:
+        struct DoNothing {
+            void operator ()(char) const {}
+        };
+
+        bool is_trail(unsigned char c) const {
+            return (c & 0xc0) == 0x80;
+        }
+
+        int trail_table(unsigned char c) const {
+            static const signed char table[] = {
+                                 /* not a lead byte */
+                /* 0x10???sss */ -1, -1, -1, -1, -1, -1, -1, -1,
+                /* 0x110??sss */ 1, 1, 1, 1, /* 1 trailing byte */
+                /* 0x1110?sss */ 2, 2, /* 2 trailing bytes */
+                /* 0x11110sss */ 3, /* 3 trailing bytes */
+                /* 0x11111sss */ -1 /* 4 or 5 trailing bytes, disallowed */
+            };
+            return table[(c & 0x7f) >> 3];
+        }
+
+        char trail(unsigned unmasked) const {
+            return static_cast<char>(0x80 | (unmasked & 0x3f));
+        }
+    };
+
+}}}}
+
+#endif
diff --git a/include/boost/property_tree/json_parser/detail/parser.hpp b/include/boost/property_tree/json_parser/detail/parser.hpp
new file mode 100644
index 0000000..5554990
--- /dev/null
+++ b/include/boost/property_tree/json_parser/detail/parser.hpp
@@ -0,0 +1,530 @@
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_PARSER_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_PARSER_HPP
+
+#include <boost/property_tree/json_parser/error.hpp>
+
+#include <boost/ref.hpp>
+#include <boost/bind.hpp>
+#include <boost/format.hpp>
+
+#include <iterator>
+#include <sstream>
+#include <string>
+
+namespace boost { namespace property_tree {
+    namespace json_parser { namespace detail
+{
+
+    template <typename Encoding, typename Iterator, typename Sentinel>
+    class source
+    {
+    public:
+        typedef typename std::iterator_traits<Iterator>::value_type
+            code_unit;
+        typedef bool (Encoding::*encoding_predicate)(code_unit c) const;
+
+        explicit source(Encoding& encoding) : encoding(encoding) {}
+
+        template <typename Range>
+        void set_input(const std::string& filename, const Range& r)
+        {
+            this->filename = filename;
+            cur = r.begin();
+            end = r.end();
+            // Note that there is no backtracking, so if e.g. a UTF-8 file
+            // starts with something that initially looks like a BOM but isn't,
+            // there's trouble.
+            // However, no valid JSON file can start with a UTF-8 EF byte.
+            encoding.skip_introduction(cur, end);
+            line = 1;
+            offset = 0;
+        }
+
+        bool done() const { return cur == end; }
+
+        void parse_error(const char* msg) {
+            BOOST_PROPERTY_TREE_THROW(
+                json_parser_error(msg, filename, line));
+        }
+
+        void next() {
+            if (encoding.is_nl(*cur)) {
+                ++line;
+                offset = 0;
+            } else {
+                ++offset;
+            }
+            ++cur;
+        }
+
+        template <typename Action>
+        bool have(encoding_predicate p, Action& a) {
+            bool found = cur != end && (encoding.*p)(*cur);
+            if (found) {
+                a(*cur);
+                next();
+            }
+            return found;
+        }
+
+        bool have(encoding_predicate p) {
+            DoNothing n;
+            return have(p, n);
+        }
+
+        template <typename Action>
+        void expect(encoding_predicate p, const char* msg, Action& a) {
+            if (!have(p, a)) {
+                parse_error(msg);
+            }
+        }
+
+        void expect(encoding_predicate p, const char* msg) {
+            DoNothing n;
+            expect(p, msg, n);
+        }
+
+        code_unit need_cur(const char* msg) {
+            if (cur == end) {
+                parse_error(msg);
+            }
+            return *cur;
+        }
+
+        Iterator& raw_cur() { return cur; }
+        Sentinel raw_end() { return end; }
+
+    private:
+        struct DoNothing {
+            void operator ()(code_unit) const {}
+        };
+
+        Encoding& encoding;
+        Iterator cur;
+        Sentinel end;
+        std::string filename;
+        int line;
+        int offset;
+    };
+
+    template <typename Callbacks, typename Encoding, typename Iterator,
+        typename = typename std::iterator_traits<Iterator>
+            ::iterator_category>
+    class number_callback_adapter
+    {
+    public:
+        number_callback_adapter(Callbacks& callbacks, Encoding& encoding,
+                                Iterator& cur)
+            : callbacks(callbacks), encoding(encoding), first(cur), cur(cur)
+        {}
+
+        void operator ()(typename Encoding::external_char) {}
+
+        void finish() const {
+            callbacks.on_number(encoding.to_internal(first, cur));
+        }
+
+    private:
+        number_callback_adapter(const number_callback_adapter&);
+
+        Callbacks& callbacks;
+        Encoding& encoding;
+        Iterator first;
+        Iterator& cur;
+    };
+
+    template <typename Callbacks, typename Encoding, typename Iterator>
+    class number_callback_adapter<Callbacks, Encoding, Iterator,
+                                  std::input_iterator_tag>
+    {
+    public:
+        number_callback_adapter(Callbacks& callbacks, Encoding& encoding,
+                                Iterator&)
+            : callbacks(callbacks), encoding(encoding), first(true)
+        {}
+
+        void operator ()(typename Encoding::external_char c) {
+            if (first) {
+                callbacks.on_begin_number();
+                first = false;
+            }
+            callbacks.on_digit(encoding.to_internal_trivial(c));
+        }
+
+        void finish() const {
+            callbacks.on_end_number();
+        }
+    private:
+        number_callback_adapter(const number_callback_adapter&);
+
+        Callbacks& callbacks;
+        Encoding& encoding;
+        bool first;
+    };
+
+    template <typename Callbacks, typename Encoding, typename Iterator,
+        typename = typename std::iterator_traits<Iterator>
+            ::iterator_category>
+    class string_callback_adapter
+    {
+    public:
+        string_callback_adapter(Callbacks& callbacks, Encoding& encoding,
+                                Iterator& cur)
+            : callbacks(callbacks), encoding(encoding), cur(cur),
+              run_begin(cur)
+        {}
+
+        void start_run() {
+            run_begin = cur;
+        }
+
+        void finish_run() {
+            callbacks.on_code_units(encoding.to_internal(run_begin, cur));
+        }
+
+        template <typename Sentinel, typename EncodingErrorFn>
+        void process_codepoint(Sentinel end, EncodingErrorFn error_fn) {
+            encoding.skip_codepoint(cur, end, error_fn);
+        }
+
+    private:
+        string_callback_adapter(const string_callback_adapter&);
+
+        Callbacks& callbacks;
+        Encoding& encoding;
+        Iterator& cur;
+        Iterator run_begin;
+    };
+
+    template <typename Callbacks, typename Encoding, typename Iterator>
+    class string_callback_adapter<Callbacks, Encoding, Iterator,
+                                  std::input_iterator_tag>
+    {
+    public:
+        string_callback_adapter(Callbacks& callbacks, Encoding& encoding,
+                                Iterator& cur)
+            : callbacks(callbacks), encoding(encoding), cur(cur)
+        {}
+
+        void start_run() {}
+
+        void finish_run() {}
+
+        template <typename Sentinel, typename EncodingErrorFn>
+        void process_codepoint(Sentinel end, EncodingErrorFn error_fn) {
+            encoding.transcode_codepoint(cur, end,
+                boost::bind(&Callbacks::on_code_unit,
+                            boost::ref(callbacks), _1),
+                error_fn);
+        }
+
+    private:
+        string_callback_adapter(const string_callback_adapter&);
+
+        Callbacks& callbacks;
+        Encoding& encoding;
+        Iterator& cur;
+    };
+
+    template <typename Callbacks, typename Encoding, typename Iterator,
+              typename Sentinel>
+    class parser
+    {
+        typedef detail::number_callback_adapter<Callbacks, Encoding, Iterator>
+            number_adapter;
+        typedef detail::string_callback_adapter<Callbacks, Encoding, Iterator>
+            string_adapter;
+        typedef detail::source<Encoding, Iterator, Sentinel> source;
+        typedef typename source::code_unit code_unit;
+
+    public:
+        parser(Callbacks& callbacks, Encoding& encoding)
+            : callbacks(callbacks), encoding(encoding), src(encoding)
+        {}
+
+        template <typename Range>
+        void set_input(const std::string& filename, const Range& r) {
+            src.set_input(filename, r);
+        }
+
+        void finish() {
+            skip_ws();
+            if (!src.done()) {
+                parse_error("garbage after data");
+            }
+        }
+
+        void parse_value() {
+            if (parse_object()) return;
+            if (parse_array()) return;
+            if (parse_string()) return;
+            if (parse_boolean()) return;
+            if (parse_null()) return;
+            if (parse_number()) return;
+            parse_error("expected value");
+        }
+
+        bool parse_null() {
+            skip_ws();
+            if (!have(&Encoding::is_n)) {
+                return false;
+            }
+            expect(&Encoding::is_u, "expected 'null'");
+            expect(&Encoding::is_l, "expected 'null'");
+            expect(&Encoding::is_l, "expected 'null'");
+            callbacks.on_null();
+            return true;
+        }
+
+        bool parse_boolean() {
+            skip_ws();
+            if (have(&Encoding::is_t)) {
+                expect(&Encoding::is_r, "expected 'true'");
+                expect(&Encoding::is_u, "expected 'true'");
+                expect(&Encoding::is_e, "expected 'true'");
+                callbacks.on_boolean(true);
+                return true;
+            }
+            if (have(&Encoding::is_f)) {
+                expect(&Encoding::is_a, "expected 'false'");
+                expect(&Encoding::is_l, "expected 'false'");
+                expect(&Encoding::is_s, "expected 'false'");
+                expect(&Encoding::is_e, "expected 'false'");
+                callbacks.on_boolean(false);
+                return true;
+            }
+            return false;
+        }
+
+        bool parse_number() {
+            skip_ws();
+
+            number_adapter adapter(callbacks, encoding, src.raw_cur());
+            bool started = false;
+            if (have(&Encoding::is_minus, adapter)) {
+                started = true;
+            }
+            if (!have(&Encoding::is_0, adapter) && !parse_int_part(adapter)) {
+                if (started) {
+                    parse_error("expected digits after -");
+                }
+                return false;
+            }
+            parse_frac_part(adapter);
+            parse_exp_part(adapter);
+            adapter.finish();
+            return true;
+        }
+
+        bool parse_string() {
+            skip_ws();
+
+            if (!have(&Encoding::is_quote)) {
+                return false;
+            }
+
+            callbacks.on_begin_string();
+            string_adapter adapter(callbacks, encoding, src.raw_cur());
+            while (!encoding.is_quote(need_cur("unterminated string"))) {
+                if (encoding.is_backslash(*src.raw_cur())) {
+                    adapter.finish_run();
+                    next();
+                    parse_escape();
+                    adapter.start_run();
+                } else {
+                    adapter.process_codepoint(src.raw_end(),
+                        boost::bind(&parser::parse_error,
+                                    this, "invalid code sequence"));
+                }
+            }
+            adapter.finish_run();
+            callbacks.on_end_string();
+            next();
+            return true;
+        }
+
+        bool parse_array() {
+            skip_ws();
+
+            if (!have(&Encoding::is_open_bracket)) {
+                return false;
+            }
+
+            callbacks.on_begin_array();
+            skip_ws();
+            if (have(&Encoding::is_close_bracket)) {
+                callbacks.on_end_array();
+                return true;
+            }
+            do {
+                parse_value();
+                skip_ws();
+            } while (have(&Encoding::is_comma));
+            expect(&Encoding::is_close_bracket, "expected ']' or ','");
+            callbacks.on_end_array();
+            return true;
+        }
+
+        bool parse_object() {
+            skip_ws();
+
+            if (!have(&Encoding::is_open_brace)) {
+                return false;
+            }
+
+            callbacks.on_begin_object();
+            skip_ws();
+            if (have(&Encoding::is_close_brace)) {
+                callbacks.on_end_object();
+                return true;
+            }
+            do {
+                if (!parse_string()) {
+                    parse_error("expected key string");
+                }
+                skip_ws();
+                expect(&Encoding::is_colon, "expected ':'");
+                parse_value();
+                skip_ws();
+            } while (have(&Encoding::is_comma));
+            expect(&Encoding::is_close_brace, "expected '}' or ','");
+            callbacks.on_end_object();
+            return true;
+        }
+
+    private:
+        typedef typename source::encoding_predicate encoding_predicate;
+
+        void parse_error(const char* msg) { src.parse_error(msg); }
+        void next() { src.next(); }
+        template <typename Action>
+        bool have(encoding_predicate p, Action& a) { return src.have(p, a); }
+        bool have(encoding_predicate p) { return src.have(p); }
+        template <typename Action>
+        void expect(encoding_predicate p, const char* msg, Action& a) {
+            src.expect(p, msg, a);
+        }
+        void expect(encoding_predicate p, const char* msg) {
+            src.expect(p, msg);
+        }
+        code_unit need_cur(const char* msg) { return src.need_cur(msg); }
+
+        void skip_ws() {
+            while (have(&Encoding::is_ws)) {
+            }
+        }
+
+        bool parse_int_part(number_adapter& action) {
+            if (!have(&Encoding::is_digit0, action)) {
+                return false;
+            }
+            parse_digits(action);
+            return true;
+        }
+
+        void parse_frac_part(number_adapter& action) {
+            if (!have(&Encoding::is_dot, action)) {
+                return;
+            }
+            expect(&Encoding::is_digit, "need at least one digit after '.'",
+                   action);
+            parse_digits(action);
+        }
+
+        void parse_exp_part(number_adapter& action) {
+            if (!have(&Encoding::is_eE, action)) {
+                return;
+            }
+            have(&Encoding::is_plusminus, action);
+            expect(&Encoding::is_digit, "need at least one digit in exponent",
+                   action);
+            parse_digits(action);
+        }
+
+        void parse_digits(number_adapter& action) {
+            while (have(&Encoding::is_digit, action)) {
+            }
+        }
+
+        void parse_escape() {
+            if (have(&Encoding::is_quote)) {
+                feed(0x22);
+            } else if (have(&Encoding::is_backslash)) {
+                feed(0x5c);
+            } else if (have(&Encoding::is_slash)) {
+                feed(0x2f);
+            } else if (have(&Encoding::is_b)) {
+                feed(0x08); // backspace
+            } else if (have(&Encoding::is_f)) {
+                feed(0x0c); // formfeed
+            } else if (have(&Encoding::is_n)) {
+                feed(0x0a); // line feed
+            } else if (have(&Encoding::is_r)) {
+                feed(0x0d); // carriage return
+            } else if (have(&Encoding::is_t)) {
+                feed(0x09); // horizontal tab
+            } else if (have(&Encoding::is_u)) {
+                parse_codepoint_ref();
+            } else {
+                parse_error("invalid escape sequence");
+            }
+        }
+
+        unsigned parse_hex_quad() {
+            unsigned codepoint = 0;
+            for (int i = 0; i < 4; ++i) {
+                int value = encoding.decode_hexdigit(
+                    need_cur("invalid escape sequence"));
+                if (value < 0) {
+                    parse_error("invalid escape sequence");
+                }
+                codepoint *= 16;
+                codepoint += value;
+                next();
+            }
+            return codepoint;
+        }
+
+        static bool is_surrogate_high(unsigned codepoint) {
+            return (codepoint & 0xfc00) == 0xd800;
+        }
+        static bool is_surrogate_low(unsigned codepoint) {
+            return (codepoint & 0xfc00) == 0xdc00;
+        }
+        static unsigned combine_surrogates(unsigned high, unsigned low) {
+            return 0x010000 + (((high & 0x3ff) << 10) | (low & 0x3ff));
+        }
+
+        void parse_codepoint_ref() {
+            unsigned codepoint = parse_hex_quad();
+            if (is_surrogate_low(codepoint)) {
+                parse_error("invalid codepoint, stray low surrogate");
+            }
+            if (is_surrogate_high(codepoint)) {
+                expect(&Encoding::is_backslash,
+                    "invalid codepoint, stray high surrogate");
+                expect(&Encoding::is_u,
+                    "expected codepoint reference after high surrogate");
+                int low = parse_hex_quad();
+                if (!is_surrogate_low(low)) {
+                    parse_error("expected low surrogate after high surrogate");
+                }
+                codepoint = combine_surrogates(codepoint, low);
+            }
+            feed(codepoint);
+        }
+
+        void feed(unsigned codepoint) {
+            encoding.feed_codepoint(codepoint,
+                                    boost::bind(&Callbacks::on_code_unit,
+                                                boost::ref(callbacks), _1));
+        }
+
+        Callbacks& callbacks;
+        Encoding& encoding;
+        source src;
+    };
+
+}}}}
+
+#endif
diff --git a/include/boost/property_tree/json_parser/detail/read.hpp b/include/boost/property_tree/json_parser/detail/read.hpp
new file mode 100644
index 0000000..d7f0ba6
--- /dev/null
+++ b/include/boost/property_tree/json_parser/detail/read.hpp
@@ -0,0 +1,90 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2015 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP
+
+#include <boost/property_tree/json_parser/detail/parser.hpp>
+#include <boost/property_tree/json_parser/detail/narrow_encoding.hpp>
+#include <boost/property_tree/json_parser/detail/wide_encoding.hpp>
+#include <boost/property_tree/json_parser/detail/standard_callbacks.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <istream>
+#include <iterator>
+#include <string>
+
+namespace boost { namespace property_tree {
+    namespace json_parser { namespace detail
+{
+
+    template <typename Iterator, typename Sentinel>
+    class minirange
+    {
+    public:
+        minirange(Iterator first, Sentinel last) : first(first), last(last) {}
+        Iterator begin() const { return first; }
+        Sentinel end() const { return last; }
+
+    private:
+        Iterator first;
+        Sentinel last;
+    };
+    template <typename Iterator, typename Sentinel>
+    minirange<Iterator, Sentinel> make_minirange(Iterator first, Sentinel last)
+    {
+        return minirange<Iterator, Sentinel>(first, last);
+    }
+
+    template <typename Iterator, typename Sentinel,
+              typename Encoding, typename Callbacks>
+    void read_json_internal(Iterator first, Sentinel last, Encoding& encoding,
+        Callbacks& callbacks, const std::string& filename)
+    {
+        BOOST_STATIC_ASSERT_MSG((boost::is_same<
+            typename std::iterator_traits<Iterator>::value_type,
+            typename Encoding::external_char>::value),
+            "Encoding is not capable of using the iterator's value type.");
+        BOOST_STATIC_ASSERT_MSG((boost::is_same<
+            typename Callbacks::char_type,
+            typename Encoding::internal_char>::value),
+            "Encoding is not capable of producing the needed character type.");
+
+        detail::parser<Callbacks, Encoding, Iterator, Sentinel>
+            parser(callbacks, encoding);
+        parser.set_input(filename, make_minirange(first, last));
+        parser.parse_value();
+        parser.finish();
+    }
+
+    template <typename Ch> struct encoding;
+    template <> struct encoding<char> : utf8_utf8_encoding {};
+    template <> struct encoding<wchar_t> : wide_wide_encoding {};
+
+    template <typename Ptree>
+    void read_json_internal(
+        std::basic_istream<typename Ptree::key_type::value_type> &stream,
+        Ptree &pt, const std::string &filename)
+    {
+        typedef typename Ptree::key_type::value_type char_type;
+        typedef standard_callbacks<Ptree> callbacks_type;
+        typedef detail::encoding<char_type> encoding_type;
+        typedef std::istreambuf_iterator<char_type> iterator;
+        callbacks_type callbacks;
+        encoding_type encoding;
+        read_json_internal(iterator(stream), iterator(),
+            encoding, callbacks, filename);
+        pt.swap(callbacks.output());
+    }
+
+}}}}
+
+#endif
diff --git a/include/boost/property_tree/json_parser/detail/standard_callbacks.hpp b/include/boost/property_tree/json_parser/detail/standard_callbacks.hpp
new file mode 100644
index 0000000..0ece280
--- /dev/null
+++ b/include/boost/property_tree/json_parser/detail/standard_callbacks.hpp
@@ -0,0 +1,153 @@
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP
+
+#include <boost/assert.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <vector>
+
+namespace boost { namespace property_tree {
+    namespace json_parser { namespace detail
+{
+
+    namespace constants
+    {
+        template <typename Ch> const Ch* null_value();
+        template <> inline const char* null_value() { return "null"; }
+        template <> inline const wchar_t* null_value() { return L"null"; }
+
+        template <typename Ch> const Ch* true_value();
+        template <> inline const char* true_value() { return "true"; }
+        template <> inline const wchar_t* true_value() { return L"true"; }
+
+        template <typename Ch> const Ch* false_value();
+        template <> inline const char* false_value() { return "false"; }
+        template <> inline const wchar_t* false_value() { return L"false"; }
+    }
+
+    template <typename Ptree>
+    class standard_callbacks {
+    public:
+        typedef typename Ptree::data_type string;
+        typedef typename string::value_type char_type;
+
+        void on_null() {
+            new_value() = constants::null_value<char_type>();
+        }
+
+        void on_boolean(bool b) {
+            new_value() = b ? constants::true_value<char_type>()
+                            : constants::false_value<char_type>();
+        }
+
+        template <typename Range>
+        void on_number(Range code_units) {
+            new_value().assign(code_units.begin(), code_units.end());
+        }
+        void on_begin_number() {
+            new_value();
+        }
+        void on_digit(char_type d) {
+            current_value() += d;
+        }
+        void on_end_number() {}
+
+        void on_begin_string() {
+            new_value();
+        }
+        template <typename Range>
+        void on_code_units(Range code_units) {
+            current_value().append(code_units.begin(), code_units.end());
+        }
+        void on_code_unit(char_type c) {
+            current_value() += c;
+        }
+        void on_end_string() {}
+
+        void on_begin_array() {
+            new_tree();
+            stack.back().k = array;
+        }
+        void on_end_array() {
+            if (stack.back().k == leaf) stack.pop_back();
+            stack.pop_back();
+        }
+
+        void on_begin_object() {
+            new_tree();
+            stack.back().k = object;
+        }
+        void on_end_object() {
+            if (stack.back().k == leaf) stack.pop_back();
+            stack.pop_back();
+        }
+
+        Ptree& output() { return root; }
+
+    protected:
+        bool is_key() const {
+            return stack.back().k == key;
+        }
+        string& current_value() {
+            layer& l = stack.back();
+            switch (l.k) {
+            case key: return key_buffer;
+            default: return l.t->data();
+            }
+        }
+
+    private:
+        Ptree root;
+        string key_buffer;
+        enum kind { array, object, key, leaf };
+        struct layer { kind k; Ptree* t; };
+        std::vector<layer> stack;
+
+        Ptree& new_tree() {
+            if (stack.empty()) {
+                layer l = {leaf, &root};
+                stack.push_back(l);
+                return root;
+            }
+            layer& l = stack.back();
+            switch (l.k) {
+            case array: {
+                l.t->push_back(std::make_pair(string(), Ptree()));
+                layer nl = {leaf, &l.t->back().second};
+                stack.push_back(nl);
+                return *stack.back().t;
+            }
+            case object:
+            default:
+                BOOST_ASSERT(false); // must start with string, i.e. call new_value
+            case key: {
+                l.t->push_back(std::make_pair(key_buffer, Ptree()));
+                l.k = object;
+                layer nl = {leaf, &l.t->back().second};
+                stack.push_back(nl);
+                return *stack.back().t;
+            }
+            case leaf:
+                stack.pop_back();
+                return new_tree();
+            }
+        }
+        string& new_value() {
+            if (stack.empty()) return new_tree().data();
+            layer& l = stack.back();
+            switch (l.k) {
+            case leaf:
+                stack.pop_back();
+                return new_value();
+            case object:
+                l.k = key;
+                key_buffer.clear();
+                return key_buffer;
+            default:
+                return new_tree().data();
+            }
+        }
+    };
+
+}}}}
+
+#endif
diff --git a/include/boost/property_tree/json_parser/detail/wide_encoding.hpp b/include/boost/property_tree/json_parser/detail/wide_encoding.hpp
new file mode 100644
index 0000000..a213ae9
--- /dev/null
+++ b/include/boost/property_tree/json_parser/detail/wide_encoding.hpp
@@ -0,0 +1,182 @@
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WIDE_ENCODING_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WIDE_ENCODING_HPP
+
+#include <boost/assert.hpp>
+#include <boost/range/iterator_range_core.hpp>
+
+#include <utility>
+
+namespace boost { namespace property_tree {
+    namespace json_parser { namespace detail
+{
+
+    struct external_wide_encoding
+    {
+        typedef wchar_t external_char;
+
+        bool is_nl(wchar_t c) const { return c == L'\n'; }
+        bool is_ws(wchar_t c) const {
+            return c == L' ' || c == L'\t' || c == L'\n' || c == L'\r';
+        }
+
+        bool is_minus(wchar_t c) const { return c == L'-'; }
+        bool is_plusminus(wchar_t c) const { return c == L'+' || c == L'-'; }
+        bool is_dot(wchar_t c) const { return c == L'.'; }
+        bool is_eE(wchar_t c) const { return c == L'e' || c == L'E'; }
+        bool is_0(wchar_t c) const { return c == L'0'; }
+        bool is_digit(wchar_t c) const { return c >= L'0' && c <= L'9'; }
+        bool is_digit0(wchar_t c) const { return c >= L'1' && c <= L'9'; }
+
+        bool is_quote(wchar_t c) const { return c == L'"'; }
+        bool is_backslash(wchar_t c) const { return c == L'\\'; }
+        bool is_slash(wchar_t c) const { return c == L'/'; }
+
+        bool is_comma(wchar_t c) const { return c == L','; }
+        bool is_open_bracket(wchar_t c) const { return c == L'['; }
+        bool is_close_bracket(wchar_t c) const { return c == L']'; }
+        bool is_colon(wchar_t c) const { return c == L':'; }
+        bool is_open_brace(wchar_t c) const { return c == L'{'; }
+        bool is_close_brace(wchar_t c) const { return c == L'}'; }
+
+        bool is_a(wchar_t c) const { return c == L'a'; }
+        bool is_b(wchar_t c) const { return c == L'b'; }
+        bool is_e(wchar_t c) const { return c == L'e'; }
+        bool is_f(wchar_t c) const { return c == L'f'; }
+        bool is_l(wchar_t c) const { return c == L'l'; }
+        bool is_n(wchar_t c) const { return c == L'n'; }
+        bool is_r(wchar_t c) const { return c == L'r'; }
+        bool is_s(wchar_t c) const { return c == L's'; }
+        bool is_t(wchar_t c) const { return c == L't'; }
+        bool is_u(wchar_t c) const { return c == L'u'; }
+
+        int decode_hexdigit(wchar_t c) {
+            if (c >= L'0' && c <= L'9') return c - L'0';
+            if (c >= L'A' && c <= L'F') return c - L'A' + 10;
+            if (c >= L'a' && c <= L'f') return c - L'a' + 10;
+            return -1;
+        }
+    };
+
+    template <bool B> struct is_utf16 {};
+
+    class wide_wide_encoding : public external_wide_encoding
+    {
+        typedef is_utf16<sizeof(wchar_t) == 2> test_utf16;
+    public:
+        typedef wchar_t internal_char;
+
+        template <typename Iterator>
+        boost::iterator_range<Iterator>
+        to_internal(Iterator first, Iterator last) const {
+            return boost::make_iterator_range(first, last);
+        }
+
+        wchar_t to_internal_trivial(wchar_t c) const {
+            BOOST_ASSERT(!is_surrogate_high(c) && !is_surrogate_low(c));
+            return c;
+        }
+
+        template <typename Iterator, typename Sentinel,
+                  typename EncodingErrorFn>
+        void skip_codepoint(Iterator& cur, Sentinel end,
+                            EncodingErrorFn error_fn) const {
+            transcode_codepoint(cur, end, DoNothing(), error_fn);
+        }
+
+        template <typename Iterator, typename Sentinel, typename TranscodedFn,
+                  typename EncodingErrorFn>
+        void transcode_codepoint(Iterator& cur, Sentinel end,
+                TranscodedFn transcoded_fn, EncodingErrorFn error_fn) const {
+            return transcode_codepoint(cur, end, transcoded_fn, error_fn,
+                                       test_utf16());
+        }
+
+        template <typename TranscodedFn>
+        void feed_codepoint(unsigned codepoint,
+                            TranscodedFn transcoded_fn) const {
+            feed_codepoint(codepoint, transcoded_fn, test_utf16());
+        }
+
+        template <typename Iterator, typename Sentinel>
+        void skip_introduction(Iterator& cur, Sentinel end) const {
+            // Endianness is already decoded at this level.
+            if (cur != end && *cur == 0xfeff) {
+                ++cur;
+            }
+        }
+
+    private:
+        struct DoNothing {
+            void operator ()(wchar_t) const {}
+        };
+
+        template <typename Iterator, typename Sentinel, typename TranscodedFn,
+                  typename EncodingErrorFn>
+        void transcode_codepoint(Iterator& cur, Sentinel,
+                                 TranscodedFn transcoded_fn,
+                                 EncodingErrorFn error_fn,
+                                 is_utf16<false>) const {
+            wchar_t c = *cur;
+            if (c < 0x20) {
+                error_fn();
+            }
+            transcoded_fn(c);
+            ++cur;
+        }
+        template <typename Iterator, typename Sentinel, typename TranscodedFn,
+                  typename EncodingErrorFn>
+        void transcode_codepoint(Iterator& cur, Sentinel end,
+                                 TranscodedFn transcoded_fn,
+                                 EncodingErrorFn error_fn,
+                                 is_utf16<true>) const {
+            wchar_t c = *cur;
+            if (c < 0x20) {
+                error_fn();
+            }
+            if (is_surrogate_low(c)) {
+                error_fn();
+            }
+            transcoded_fn(c);
+            ++cur;
+            if (is_surrogate_high(c)) {
+                if (cur == end) {
+                    error_fn();
+                }
+                c = *cur;
+                if (!is_surrogate_low(c)) {
+                    error_fn();
+                }
+                transcoded_fn(c);
+                ++cur;
+            }
+        }
+
+        template <typename TranscodedFn>
+        void feed_codepoint(unsigned codepoint, TranscodedFn transcoded_fn,
+                            is_utf16<false>) const {
+            transcoded_fn(static_cast<wchar_t>(codepoint));
+        }
+        template <typename TranscodedFn>
+        void feed_codepoint(unsigned codepoint, TranscodedFn transcoded_fn,
+                            is_utf16<true>) const {
+            if (codepoint < 0x10000) {
+                transcoded_fn(static_cast<wchar_t>(codepoint));
+            } else {
+                codepoint -= 0x10000;
+                transcoded_fn(static_cast<wchar_t>((codepoint >> 10) | 0xd800));
+                transcoded_fn(static_cast<wchar_t>(
+                    (codepoint & 0x3ff) | 0xdc00));
+            }
+        }
+
+        static bool is_surrogate_high(unsigned codepoint) {
+            return (codepoint & 0xfc00) == 0xd800;
+        }
+        static bool is_surrogate_low(unsigned codepoint) {
+            return (codepoint & 0xfc00) == 0xdc00;
+        }
+    };
+
+}}}}
+
+#endif
diff --git a/include/boost/property_tree/json_parser/detail/write.hpp b/include/boost/property_tree/json_parser/detail/write.hpp
new file mode 100644
index 0000000..bba1003
--- /dev/null
+++ b/include/boost/property_tree/json_parser/detail/write.hpp
@@ -0,0 +1,168 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <string>
+#include <ostream>
+#include <iomanip>
+
+namespace boost { namespace property_tree { namespace json_parser
+{
+
+    // Create necessary escape sequences from illegal characters
+    template<class Ch>
+    std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s)
+    {
+        std::basic_string<Ch> result;
+        typename std::basic_string<Ch>::const_iterator b = s.begin();
+        typename std::basic_string<Ch>::const_iterator e = s.end();
+        while (b != e)
+        {
+            typedef typename make_unsigned<Ch>::type UCh;
+            UCh c(*b);
+            // This assumes an ASCII superset. But so does everything in PTree.
+            // We escape everything outside ASCII, because this code can't
+            // handle high unicode characters.
+            if (c == 0x20 || c == 0x21 || (c >= 0x23 && c <= 0x2E) ||
+                (c >= 0x30 && c <= 0x5B) || (c >= 0x5D && c <= 0xFF))
+                result += *b;
+            else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
+            else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
+            else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
+            else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
+            else if (*b == Ch('\t')) result += Ch('\\'), result += Ch('t');
+            else if (*b == Ch('/')) result += Ch('\\'), result += Ch('/');
+            else if (*b == Ch('"'))  result += Ch('\\'), result += Ch('"');
+            else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
+            else
+            {
+                const char *hexdigits = "0123456789ABCDEF";
+                unsigned long u = (std::min)(static_cast<unsigned long>(
+                                                 static_cast<UCh>(*b)),
+                                             0xFFFFul);
+                unsigned long d1 = u / 4096; u -= d1 * 4096;
+                unsigned long d2 = u / 256; u -= d2 * 256;
+                unsigned long d3 = u / 16; u -= d3 * 16;
+                unsigned long d4 = u;
+                result += Ch('\\'); result += Ch('u');
+                result += Ch(hexdigits[d1]); result += Ch(hexdigits[d2]);
+                result += Ch(hexdigits[d3]); result += Ch(hexdigits[d4]);
+            }
+            ++b;
+        }
+        return result;
+    }
+
+    template<class Ptree>
+    void write_json_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream, 
+                           const Ptree &pt,
+                           int indent, bool pretty)
+    {
+
+        typedef typename Ptree::key_type::value_type Ch;
+        typedef typename std::basic_string<Ch> Str;
+
+        // Value or object or array
+        if (indent > 0 && pt.empty())
+        {
+            // Write value
+            Str data = create_escapes(pt.template get_value<Str>());
+            stream << Ch('"') << data << Ch('"');
+
+        }
+        else if (indent > 0 && pt.count(Str()) == pt.size())
+        {
+            // Write array
+            stream << Ch('[');
+            if (pretty) stream << Ch('\n');
+            typename Ptree::const_iterator it = pt.begin();
+            for (; it != pt.end(); ++it)
+            {
+                if (pretty) stream << Str(4 * (indent + 1), Ch(' '));
+                write_json_helper(stream, it->second, indent + 1, pretty);
+                if (boost::next(it) != pt.end())
+                    stream << Ch(',');
+                if (pretty) stream << Ch('\n');
+            }
+            if (pretty) stream << Str(4 * indent, Ch(' '));
+            stream << Ch(']');
+
+        }
+        else
+        {
+            // Write object
+            stream << Ch('{');
+            if (pretty) stream << Ch('\n');
+            typename Ptree::const_iterator it = pt.begin();
+            for (; it != pt.end(); ++it)
+            {
+                if (pretty) stream << Str(4 * (indent + 1), Ch(' '));
+                stream << Ch('"') << create_escapes(it->first) << Ch('"') << Ch(':');
+                if (pretty) stream << Ch(' ');
+                write_json_helper(stream, it->second, indent + 1, pretty);
+                if (boost::next(it) != pt.end())
+                    stream << Ch(',');
+                if (pretty) stream << Ch('\n');
+            }
+            if (pretty) stream << Str(4 * indent, Ch(' '));
+            stream << Ch('}');
+        }
+
+    }
+
+    // Verify if ptree does not contain information that cannot be written to json
+    template<class Ptree>
+    bool verify_json(const Ptree &pt, int depth)
+    {
+
+        typedef typename Ptree::key_type::value_type Ch;
+        typedef typename std::basic_string<Ch> Str;
+
+        // Root ptree cannot have data
+        if (depth == 0 && !pt.template get_value<Str>().empty())
+            return false;
+        
+        // Ptree cannot have both children and data
+        if (!pt.template get_value<Str>().empty() && !pt.empty())
+            return false;
+
+        // Check children
+        typename Ptree::const_iterator it = pt.begin();
+        for (; it != pt.end(); ++it)
+            if (!verify_json(it->second, depth + 1))
+                return false;
+
+        // Success
+        return true;
+
+    }
+    
+    // Write ptree to json stream
+    template<class Ptree>
+    void write_json_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream, 
+                             const Ptree &pt,
+                             const std::string &filename,
+                             bool pretty)
+    {
+        if (!verify_json(pt, 0))
+            BOOST_PROPERTY_TREE_THROW(json_parser_error("ptree contains data that cannot be represented in JSON format", filename, 0));
+        write_json_helper(stream, pt, 0, pretty);
+        stream << std::endl;
+        if (!stream.good())
+            BOOST_PROPERTY_TREE_THROW(json_parser_error("write error", filename, 0));
+    }
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/json_parser/error.hpp b/include/boost/property_tree/json_parser/error.hpp
new file mode 100644
index 0000000..d48c72f
--- /dev/null
+++ b/include/boost/property_tree/json_parser/error.hpp
@@ -0,0 +1,33 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED
+
+#include <boost/property_tree/detail/file_parser_error.hpp>
+#include <string>
+
+namespace boost { namespace property_tree { namespace json_parser
+{
+
+    //! Json parser error
+    class json_parser_error: public file_parser_error
+    {
+    public:
+        json_parser_error(const std::string &message, 
+                          const std::string &filename, 
+                          unsigned long line): 
+            file_parser_error(message, filename, line)
+        { 
+        }
+    };
+
+} } }
+
+#endif
diff --git a/include/boost/property_tree/ptree.hpp b/include/boost/property_tree/ptree.hpp
new file mode 100644
index 0000000..9e7b921
--- /dev/null
+++ b/include/boost/property_tree/ptree.hpp
@@ -0,0 +1,518 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+#include <boost/property_tree/string_path.hpp>
+#include <boost/property_tree/stream_translator.hpp>
+#include <boost/property_tree/exceptions.hpp>
+#include <boost/property_tree/detail/ptree_utils.hpp>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/indexed_by.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/optional.hpp>
+#include <utility>                  // for std::pair
+
+namespace boost { namespace property_tree
+{
+
+    /**
+     * Property tree main structure. A property tree is a hierarchical data
+     * structure which has one element of type @p Data in each node, as well
+     * as an ordered sequence of sub-nodes, which are additionally identified
+     * by a non-unique key of type @p Key.
+     *
+     * Key equivalency is defined by @p KeyCompare, a predicate defining a
+     * strict weak ordering.
+     *
+     * Property tree defines a Container-like interface to the (key-node) pairs
+     * of its direct sub-nodes. The iterators are bidirectional. The sequence
+     * of nodes is held in insertion order, not key order.
+     */
+    template<class Key, class Data, class KeyCompare>
+    class basic_ptree
+    {
+#if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
+    public:
+#endif
+        // Internal types
+        /**
+         * Simpler way to refer to this basic_ptree\<C,K,P,A\> type.
+         * Note that this is private, and made public only for doxygen.
+         */
+        typedef basic_ptree<Key, Data, KeyCompare> self_type;
+
+    public:
+        // Basic types
+        typedef Key                                  key_type;
+        typedef Data                                 data_type;
+        typedef KeyCompare                           key_compare;
+
+        // Container view types
+        typedef std::pair<const Key, self_type>      value_type;
+        typedef std::size_t                          size_type;
+
+        // The problem with the iterators is that I can't make them complete
+        // until the container is complete. Sucks. Especially for the reverses.
+        class iterator;
+        class const_iterator;
+        class reverse_iterator;
+        class const_reverse_iterator;
+
+        // Associative view types
+        class assoc_iterator;
+        class const_assoc_iterator;
+
+        // Property tree view types
+        typedef typename path_of<Key>::type          path_type;
+
+
+        // The big five
+
+        /** Creates a node with no children and default-constructed data. */
+        basic_ptree();
+        /** Creates a node with no children and a copy of the given data. */
+        explicit basic_ptree(const data_type &data);
+        basic_ptree(const self_type &rhs);
+        ~basic_ptree();
+        /** Basic guarantee only. */
+        self_type &operator =(const self_type &rhs);
+
+        /** Swap with other tree. Only constant-time and nothrow if the
+         * data type's swap is.
+         */
+        void swap(self_type &rhs);
+
+        // Container view functions
+
+        /** The number of direct children of this node. */
+        size_type size() const;
+        size_type max_size() const;
+        /** Whether there are any direct children. */
+        bool empty() const;
+
+        iterator begin();
+        const_iterator begin() const;
+        iterator end();
+        const_iterator end() const;
+        reverse_iterator rbegin();
+        const_reverse_iterator rbegin() const;
+        reverse_iterator rend();
+        const_reverse_iterator rend() const;
+
+        value_type &front();
+        const value_type &front() const;
+        value_type &back();
+        const value_type &back() const;
+
+        /** Insert a copy of the given tree with its key just before the given
+         * position in this node. This operation invalidates no iterators.
+         * @return An iterator to the newly created child.
+         */
+        iterator insert(iterator where, const value_type &value);
+
+        /** Range insert. Equivalent to:
+         * @code
+         * for(; first != last; ++first) insert(where, *first);
+         * @endcode
+         */
+        template<class It> void insert(iterator where, It first, It last);
+
+        /** Erase the child pointed at by the iterator. This operation
+         * invalidates the given iterator, as well as its equivalent
+         * assoc_iterator.
+         * @return A valid iterator pointing to the element after the erased.
+         */
+        iterator erase(iterator where);
+
+        /** Range erase. Equivalent to:
+         * @code
+         * while(first != last;) first = erase(first);
+         * @endcode
+         */
+        iterator erase(iterator first, iterator last);
+
+        /** Equivalent to insert(begin(), value). */
+        iterator push_front(const value_type &value);
+
+        /** Equivalent to insert(end(), value). */
+        iterator push_back(const value_type &value);
+
+        /** Equivalent to erase(begin()). */
+        void pop_front();
+
+        /** Equivalent to erase(boost::prior(end())). */
+        void pop_back();
+
+        /** Reverses the order of direct children in the property tree. */
+        void reverse();
+
+        /** Sorts the direct children of this node according to the predicate.
+         * The predicate is passed the whole pair of key and child.
+         */
+        template<class Compare> void sort(Compare comp);
+
+        /** Sorts the direct children of this node according to key order. */
+        void sort();
+
+        // Equality
+
+        /** Two property trees are the same if they have the same data, the keys
+         * and order of their children are the same, and the children compare
+         * equal, recursively.
+         */
+        bool operator ==(const self_type &rhs) const;
+        bool operator !=(const self_type &rhs) const;
+
+        // Associative view
+
+        /** Returns an iterator to the first child, in key order. */
+        assoc_iterator ordered_begin();
+        /** Returns an iterator to the first child, in key order. */
+        const_assoc_iterator ordered_begin() const;
+
+        /** Returns the not-found iterator. Equivalent to end() in a real
+         * associative container.
+         */
+        assoc_iterator not_found();
+        /** Returns the not-found iterator. Equivalent to end() in a real
+         * associative container.
+         */
+        const_assoc_iterator not_found() const;
+
+        /** Find a child with the given key, or not_found() if there is none.
+         * There is no guarantee about which child is returned if multiple have
+         * the same key.
+         */
+        assoc_iterator find(const key_type &key);
+
+        /** Find a child with the given key, or not_found() if there is none.
+         * There is no guarantee about which child is returned if multiple have
+         * the same key.
+         */
+        const_assoc_iterator find(const key_type &key) const;
+
+        /** Find the range of children that have the given key. */
+        std::pair<assoc_iterator, assoc_iterator>
+            equal_range(const key_type &key);
+
+        /** Find the range of children that have the given key. */
+        std::pair<const_assoc_iterator, const_assoc_iterator>
+            equal_range(const key_type &key) const;
+
+        /** Count the number of direct children with the given key. */
+        size_type count(const key_type &key) const;
+
+        /** Erase all direct children with the given key and return the count.
+         */
+        size_type erase(const key_type &key);
+
+        /** Get the iterator that points to the same element as the argument.
+         * @note A valid assoc_iterator range (a, b) does not imply that
+         *       (to_iterator(a), to_iterator(b)) is a valid range.
+         */
+        iterator to_iterator(assoc_iterator it);
+
+        /** Get the iterator that points to the same element as the argument.
+         * @note A valid const_assoc_iterator range (a, b) does not imply that
+         *       (to_iterator(a), to_iterator(b)) is a valid range.
+         */
+        const_iterator to_iterator(const_assoc_iterator it) const;
+
+        // Property tree view
+
+        /** Reference to the actual data in this node. */
+        data_type &data();
+
+        /** Reference to the actual data in this node. */
+        const data_type &data() const;
+
+        /** Clear this tree completely, of both data and children. */
+        void clear();
+
+        /** Get the child at the given path, or throw @c ptree_bad_path.
+         * @note Depending on the path, the result at each level may not be
+         *       completely deterministic, i.e. if the same key appears multiple
+         *       times, which child is chosen is not specified. This can lead
+         *       to the path not being resolved even though there is a
+         *       descendant with this path. Example:
+         * @code
+         *   a -> b -> c
+         *     -> b
+         * @endcode
+         *       The path "a.b.c" will succeed if the resolution of "b" chooses
+         *       the first such node, but fail if it chooses the second.
+         */
+        self_type &get_child(const path_type &path);
+
+        /** Get the child at the given path, or throw @c ptree_bad_path. */
+        const self_type &get_child(const path_type &path) const;
+
+        /** Get the child at the given path, or return @p default_value. */
+        self_type &get_child(const path_type &path, self_type &default_value);
+
+        /** Get the child at the given path, or return @p default_value. */
+        const self_type &get_child(const path_type &path,
+                                   const self_type &default_value) const;
+
+        /** Get the child at the given path, or return boost::null. */
+        optional<self_type &> get_child_optional(const path_type &path);
+
+        /** Get the child at the given path, or return boost::null. */
+        optional<const self_type &>
+          get_child_optional(const path_type &path) const;
+
+        /** Set the node at the given path to the given value. Create any
+         * missing parents. If the node at the path already exists, replace it.
+         * @return A reference to the inserted subtree.
+         * @note Because of the way paths work, it is not generally guaranteed
+         *       that a node newly created can be accessed using the same path.
+         * @note If the path could refer to multiple nodes, it is unspecified
+         *       which one gets replaced.
+         */
+        self_type &put_child(const path_type &path, const self_type &value);
+
+        /** Add the node at the given path. Create any missing parents. If there
+         * already is a node at the path, add another one with the same key.
+         * @param path Path to the child. The last fragment must not have an
+         *             index.
+         * @return A reference to the inserted subtree.
+         * @note Because of the way paths work, it is not generally guaranteed
+         *       that a node newly created can be accessed using the same path.
+         */
+        self_type &add_child(const path_type &path, const self_type &value);
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the supplied translator.
+         * @throw ptree_bad_data if the conversion fails.
+         */
+        template<class Type, class Translator>
+        typename boost::enable_if<detail::is_translator<Translator>, Type>::type
+        get_value(Translator tr) const;
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the default translator.
+         * @throw ptree_bad_data if the conversion fails.
+         */
+        template<class Type>
+        Type get_value() const;
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the supplied translator. Return @p default_value
+         * if this fails.
+         */
+        template<class Type, class Translator>
+        Type get_value(const Type &default_value, Translator tr) const;
+
+        /** Make get_value do the right thing for string literals. */
+        template <class Ch, class Translator>
+        typename boost::enable_if<
+            detail::is_character<Ch>,
+            std::basic_string<Ch>
+        >::type
+        get_value(const Ch *default_value, Translator tr) const;
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the default translator. Return @p default_value
+         * if this fails.
+         */
+        template<class Type>
+        typename boost::disable_if<detail::is_translator<Type>, Type>::type
+        get_value(const Type &default_value) const;
+
+        /** Make get_value do the right thing for string literals. */
+        template <class Ch>
+        typename boost::enable_if<
+            detail::is_character<Ch>,
+            std::basic_string<Ch>
+        >::type
+        get_value(const Ch *default_value) const;
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the supplied translator. Return boost::null if
+         * this fails.
+         */
+        template<class Type, class Translator>
+        optional<Type> get_value_optional(Translator tr) const;
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the default translator. Return boost::null if
+         * this fails.
+         */
+        template<class Type>
+        optional<Type> get_value_optional() const;
+
+        /** Replace the value at this node with the given value, translated
+         * to the tree's data type using the supplied translator.
+         * @throw ptree_bad_data if the conversion fails.
+        */
+        template<class Type, class Translator>
+        void put_value(const Type &value, Translator tr);
+
+        /** Replace the value at this node with the given value, translated
+         * to the tree's data type using the default translator.
+         * @throw ptree_bad_data if the conversion fails.
+        */
+        template<class Type>
+        void put_value(const Type &value);
+
+        /** Shorthand for get_child(path).get_value(tr). */
+        template<class Type, class Translator>
+        typename boost::enable_if<detail::is_translator<Translator>, Type>::type
+        get(const path_type &path, Translator tr) const;
+
+        /** Shorthand for get_child(path).get_value\<Type\>(). */
+        template<class Type>
+        Type get(const path_type &path) const;
+
+        /** Shorthand for get_child(path, empty_ptree())
+         *                    .get_value(default_value, tr).
+         * That is, return the translated value if possible, and the default
+         * value if the node doesn't exist or conversion fails.
+         */
+        template<class Type, class Translator>
+        Type get(const path_type &path,
+                 const Type &default_value,
+                 Translator tr) const;
+
+        /** Make get do the right thing for string literals. */
+        template <class Ch, class Translator>
+        typename boost::enable_if<
+            detail::is_character<Ch>,
+            std::basic_string<Ch>
+        >::type
+        get(const path_type &path, const Ch *default_value, Translator tr)const;
+
+        /** Shorthand for get_child(path, empty_ptree())
+         *                    .get_value(default_value).
+         * That is, return the translated value if possible, and the default
+         * value if the node doesn't exist or conversion fails.
+         */
+        template<class Type>
+        typename boost::disable_if<detail::is_translator<Type>, Type>::type
+        get(const path_type &path, const Type &default_value) const;
+
+        /** Make get do the right thing for string literals. */
+        template <class Ch>
+        typename boost::enable_if<
+            detail::is_character<Ch>,
+            std::basic_string<Ch>
+        >::type
+        get(const path_type &path, const Ch *default_value) const;
+
+        /** Shorthand for:
+         * @code
+         * if(optional\<self_type&\> node = get_child_optional(path))
+         *   return node->get_value_optional(tr);
+         * return boost::null;
+         * @endcode
+         * That is, return the value if it exists and can be converted, or nil.
+        */
+        template<class Type, class Translator>
+        optional<Type> get_optional(const path_type &path, Translator tr) const;
+
+        /** Shorthand for:
+         * @code
+         * if(optional\<const self_type&\> node = get_child_optional(path))
+         *   return node->get_value_optional();
+         * return boost::null;
+         * @endcode
+         * That is, return the value if it exists and can be converted, or nil.
+        */
+        template<class Type>
+        optional<Type> get_optional(const path_type &path) const;
+
+        /** Set the value of the node at the given path to the supplied value,
+         * translated to the tree's data type. If the node doesn't exist, it is
+         * created, including all its missing parents.
+         * @return The node that had its value changed.
+         * @throw ptree_bad_data if the conversion fails.
+        */
+        template<class Type, class Translator>
+        self_type &put(const path_type &path, const Type &value, Translator tr);
+
+        /** Set the value of the node at the given path to the supplied value,
+         * translated to the tree's data type. If the node doesn't exist, it is
+         * created, including all its missing parents.
+         * @return The node that had its value changed.
+         * @throw ptree_bad_data if the conversion fails.
+        */
+        template<class Type>
+        self_type &put(const path_type &path, const Type &value);
+
+        /** If the node identified by the path does not exist, create it,
+         * including all its missing parents.
+         * If the node already exists, add a sibling with the same key.
+         * Set the newly created node's value to the given paremeter,
+         * translated with the supplied translator.
+         * @param path Path to the child. The last fragment must not have an
+         *             index.
+         * @param value The value to add.
+         * @param tr The translator to use.
+         * @return The node that was added.
+         * @throw ptree_bad_data if the conversion fails.
+        */
+        template<class Type, class Translator>
+        self_type &add(const path_type &path,
+                       const Type &value,
+                       Translator tr);
+
+        /** If the node identified by the path does not exist, create it,
+         * including all its missing parents.
+         * If the node already exists, add a sibling with the same key.
+         * Set the newly created node's value to the given paremeter,
+         * translated with the supplied translator.
+         * @param path Path to the child. The last fragment must not have an
+         *             index.
+         * @param value The value to add.
+         * @return The node that was added.
+         * @throw ptree_bad_data if the conversion fails.
+        */
+        template<class Type>
+        self_type &add(const path_type &path, const Type &value);
+
+    private:
+        // Hold the data of this node
+        data_type m_data;
+        // Hold the children - this is a void* because we can't complete the
+        // container type within the class.
+        void* m_children;
+
+        // Getter tree-walk. Not const-safe! Gets the node the path refers to,
+        // or null. Destroys p's value.
+        self_type* walk_path(path_type& p) const;
+
+        // Modifer tree-walk. Gets the parent of the node referred to by the
+        // path, creating nodes as necessary. p is the path to the remaining
+        // child.
+        self_type& force_path(path_type& p);
+
+        // This struct contains typedefs for the concrete types.
+        struct subs;
+        friend struct subs;
+        friend class iterator;
+        friend class const_iterator;
+        friend class reverse_iterator;
+        friend class const_reverse_iterator;
+    };
+
+}}
+
+#include <boost/property_tree/detail/ptree_implementation.hpp>
+
+#endif
diff --git a/include/boost/property_tree/ptree_fwd.hpp b/include/boost/property_tree/ptree_fwd.hpp
new file mode 100644
index 0000000..fe36741
--- /dev/null
+++ b/include/boost/property_tree/ptree_fwd.hpp
@@ -0,0 +1,143 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/optional/optional_fwd.hpp>
+#include <boost/throw_exception.hpp>
+#include <functional>           // for std::less
+#include <memory>               // for std::allocator
+#include <string>
+
+namespace boost { namespace property_tree
+{
+    namespace detail {
+        template <typename T> struct less_nocase;
+    }
+
+    // Classes
+
+    template < class Key, class Data, class KeyCompare = std::less<Key> >
+    class basic_ptree;
+
+    template <typename T>
+    struct id_translator;
+
+    template <typename String, typename Translator>
+    class string_path;
+
+    // Texas-style concepts for documentation only.
+#if 0
+    concept PropertyTreePath<class Path> {
+        // The key type for which this path works.
+        typename key_type;
+        // Return the key that the first segment of the path names.
+        // Split the head off the state.
+        key_type Path::reduce();
+
+        // Return true if the path is empty.
+        bool Path::empty() const;
+
+        // Return true if the path contains a single element.
+        bool Path::single() const;
+
+        // Dump as a std::string, for exception messages.
+        std::string Path::dump() const;
+    }
+    concept PropertyTreeKey<class Key> {
+        PropertyTreePath path;
+        requires SameType<Key, PropertyTreePath<path>::key_type>;
+    }
+    concept PropertyTreeTranslator<class Tr> {
+        typename internal_type;
+        typename external_type;
+
+        boost::optional<external_type> Tr::get_value(internal_type);
+        boost::optional<internal_type> Tr::put_value(external_type);
+    }
+#endif
+    /// If you want to use a custom key type, specialize this struct for it
+    /// and give it a 'type' typedef that specifies your path type. The path
+    /// type must conform to the Path concept described in the documentation.
+    /// This is already specialized for std::basic_string.
+    template <typename Key>
+    struct path_of;
+
+    /// Specialize this struct to specify a default translator between the data
+    /// in a tree whose data_type is Internal, and the external data_type
+    /// specified in a get_value, get, put_value or put operation.
+    /// This is already specialized for Internal being std::basic_string.
+    template <typename Internal, typename External>
+    struct translator_between;
+
+    class ptree_error;
+    class ptree_bad_data;
+    class ptree_bad_path;
+
+    // Typedefs
+
+    /** Implements a path using a std::string as the key. */
+    typedef string_path<std::string, id_translator<std::string> > path;
+
+    /**
+     * A property tree with std::string for key and data, and default
+     * comparison.
+     */
+    typedef basic_ptree<std::string, std::string> ptree;
+
+    /**
+     * A property tree with std::string for key and data, and case-insensitive
+     * comparison.
+     */
+    typedef basic_ptree<std::string, std::string,
+                        detail::less_nocase<std::string> >
+        iptree;
+
+#ifndef BOOST_NO_STD_WSTRING
+    /** Implements a path using a std::wstring as the key. */
+    typedef string_path<std::wstring, id_translator<std::wstring> > wpath;
+
+    /**
+     * A property tree with std::wstring for key and data, and default
+     * comparison.
+     * @note The type only exists if the platform supports @c wchar_t.
+     */
+    typedef basic_ptree<std::wstring, std::wstring> wptree;
+
+    /**
+     * A property tree with std::wstring for key and data, and case-insensitive
+     * comparison.
+     * @note The type only exists if the platform supports @c wchar_t.
+     */
+    typedef basic_ptree<std::wstring, std::wstring,
+                        detail::less_nocase<std::wstring> >
+        wiptree;
+#endif
+
+    // Free functions
+
+    /**
+     * Swap two property tree instances.
+     */
+    template<class K, class D, class C>
+    void swap(basic_ptree<K, D, C> &pt1,
+              basic_ptree<K, D, C> &pt2);
+
+} }
+
+
+#if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
+    // Throwing macro to avoid no return warnings portably
+#   define BOOST_PROPERTY_TREE_THROW(e) BOOST_THROW_EXCEPTION(e)
+#endif
+
+#endif
diff --git a/include/boost/property_tree/ptree_serialization.hpp b/include/boost/property_tree/ptree_serialization.hpp
new file mode 100644
index 0000000..a8181ca
--- /dev/null
+++ b/include/boost/property_tree/ptree_serialization.hpp
@@ -0,0 +1,129 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/collections_save_imp.hpp>
+#include <boost/serialization/detail/stack_constructor.hpp>
+#include <boost/serialization/split_free.hpp>
+#include <boost/serialization/utility.hpp>
+
+namespace boost { namespace property_tree
+{
+
+    ///////////////////////////////////////////////////////////////////////////
+    // boost::serialization support
+
+    /**
+     * Serialize the property tree to the given archive.
+     * @note In addition to serializing to regular archives, this supports
+     *       serializing to archives requiring name-value pairs, e.g. XML
+     *       archives.  However, the output format in the XML archive is not
+     *       guaranteed to be the same as that when using the Boost.PropertyTree
+     *       library's @c boost::property_tree::xml_parser::write_xml.
+     * @param ar The archive to which to save the serialized property tree.
+     *           This archive should conform to the concept laid out by the
+     *           Boost.Serialization library.
+     * @param t The property tree to serialize.
+     * @param file_version file_version for the archive.
+     * @post @c ar will contain the serialized form of @c t.
+     */
+    template<class Archive, class K, class D, class C>
+    inline void save(Archive &ar,
+                     const basic_ptree<K, D, C> &t,
+                     const unsigned int file_version)
+    {
+        using namespace boost::serialization;
+        stl::save_collection<Archive, basic_ptree<K, D, C> >(ar, t);
+        ar << make_nvp("data", t.data());
+    }
+
+    namespace detail
+    {
+        template <class Archive, class K, class D, class C>
+        inline void load_children(Archive &ar,
+                                  basic_ptree<K, D, C> &t)
+        {
+            namespace bsl = boost::serialization;
+            namespace bsa = boost::archive;
+
+            typedef basic_ptree<K, D, C> tree;
+            typedef typename tree::value_type value_type;
+    
+            bsl::collection_size_type count;
+            ar >> BOOST_SERIALIZATION_NVP(count);
+            bsl::item_version_type item_version(0);
+            const bsa::library_version_type library_version(
+                ar.get_library_version()
+            );
+            if(bsa::library_version_type(3) < library_version){
+                ar >> BOOST_SERIALIZATION_NVP(item_version);
+            }
+            // Can't use the serialization helper, it expects resize() to exist
+            // for default-constructible elements.
+            // This is a copy/paste of the fallback version.
+            t.clear();
+            while(count-- > 0){
+                bsl::detail::stack_construct<Archive, value_type>
+                    u(ar, item_version);
+                ar >> bsl::make_nvp("item", u.reference());
+                t.push_back(u.reference());
+                ar.reset_object_address(& t.back() , & u.reference());
+            }
+        }
+    }
+
+    /**
+     * De-serialize the property tree to the given archive.
+     * @note In addition to de-serializing from regular archives, this supports
+     *       loading from archives requiring name-value pairs, e.g. XML
+     *       archives. The format should be that used by
+     *       boost::property_tree::save.
+     * @param ar The archive from which to load the serialized property tree.
+     *           This archive should conform to the concept laid out by the
+     *           Boost.Serialization library.
+     * @param t The property tree to de-serialize.
+     * @param file_version file_version for the archive.
+     * @post @c t will contain the de-serialized data from @c ar.
+     */
+    template<class Archive, class K, class D, class C>
+    inline void load(Archive &ar,
+                     basic_ptree<K, D, C> &t,
+                     const unsigned int file_version)
+    {
+        namespace bsl = boost::serialization;
+
+        detail::load_children(ar, t);
+        ar >> bsl::make_nvp("data", t.data());
+    }
+
+    /**
+     * Load or store the property tree using the given archive.
+     * @param ar The archive from which to load or save the serialized property
+     *           tree. The type of this archive will determine whether saving or
+     *           loading is performed.
+     * @param t The property tree to load or save.
+     * @param file_version file_version for the archive.
+     */
+    template<class Archive, class K, class D, class C>
+    inline void serialize(Archive &ar,
+                          basic_ptree<K, D, C> &t,
+                          const unsigned int file_version)
+    {
+        using namespace boost::serialization;
+        split_free(ar, t, file_version);
+    }
+
+} }
+
+#endif
diff --git a/include/boost/property_tree/stream_translator.hpp b/include/boost/property_tree/stream_translator.hpp
new file mode 100644
index 0000000..6e16c63
--- /dev/null
+++ b/include/boost/property_tree/stream_translator.hpp
@@ -0,0 +1,229 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+
+#include <boost/optional.hpp>
+#include <boost/optional/optional_io.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <sstream>
+#include <string>
+#include <locale>
+#include <limits>
+
+namespace boost { namespace property_tree
+{
+
+    template <typename Ch, typename Traits, typename E, typename Enabler = void>
+    struct customize_stream
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, const E& e) {
+            s << e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, E& e) {
+            s >> e;
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    // No whitespace skipping for single characters.
+    template <typename Ch, typename Traits>
+    struct customize_stream<Ch, Traits, Ch, void>
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, Ch e) {
+            s << e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, Ch& e) {
+            s.unsetf(std::ios_base::skipws);
+            s >> e;
+        }
+    };
+
+    // Ugly workaround for numeric_traits that don't have members when not
+    // specialized, e.g. MSVC.
+    namespace detail
+    {
+        template <bool is_specialized>
+        struct is_inexact_impl
+        {
+            template <typename T>
+            struct test
+            {
+                typedef boost::false_type type;
+            };
+        };
+        template <>
+        struct is_inexact_impl<true>
+        {
+            template <typename T>
+            struct test
+            {
+              typedef boost::integral_constant<bool,
+                  !std::numeric_limits<T>::is_exact> type;
+            };
+        };
+
+        template <typename F>
+        struct is_inexact
+        {
+            typedef typename boost::decay<F>::type decayed;
+            typedef typename is_inexact_impl<
+                std::numeric_limits<decayed>::is_specialized
+            >::BOOST_NESTED_TEMPLATE test<decayed>::type type;
+            static const bool value = type::value;
+        };
+    }
+
+    template <typename Ch, typename Traits, typename F>
+    struct customize_stream<Ch, Traits, F,
+        typename boost::enable_if< detail::is_inexact<F> >::type
+    >
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, const F& e) {
+#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS 
+            s.precision(std::numeric_limits<F>::max_digits10); 
+#else 
+            s.precision(std::numeric_limits<F>::digits10 + 2); 
+#endif 
+            s << e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, F& e) {
+            s >> e;
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    template <typename Ch, typename Traits>
+    struct customize_stream<Ch, Traits, bool, void>
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, bool e) {
+            s.setf(std::ios_base::boolalpha);
+            s << e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, bool& e) {
+            s >> e;
+            if(s.fail()) {
+                // Try again in word form.
+                s.clear();
+                s.setf(std::ios_base::boolalpha);
+                s >> e;
+            }
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    template <typename Ch, typename Traits>
+    struct customize_stream<Ch, Traits, signed char, void>
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, signed char e) {
+            s << (int)e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, signed char& e) {
+            int i;
+            s >> i;
+            // out of range?
+            if(i > (std::numeric_limits<signed char>::max)() ||
+                i < (std::numeric_limits<signed char>::min)())
+            {
+                s.clear(); // guarantees eof to be unset
+                e = 0;
+                s.setstate(std::ios_base::badbit);
+                return;
+            }
+            e = (signed char)i;
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    template <typename Ch, typename Traits>
+    struct customize_stream<Ch, Traits, unsigned char, void>
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, unsigned char e) {
+            s << (unsigned)e;
+        }
+        static void extract(std::basic_istream<Ch,Traits>& s, unsigned char& e){
+            unsigned i;
+            s >> i;
+            // out of range?
+            if(i > (std::numeric_limits<unsigned char>::max)()) {
+                s.clear(); // guarantees eof to be unset
+                e = 0;
+                s.setstate(std::ios_base::badbit);
+                return;
+            }
+            e = (unsigned char)i;
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    /// Implementation of Translator that uses the stream overloads.
+    template <typename Ch, typename Traits, typename Alloc, typename E>
+    class stream_translator
+    {
+        typedef customize_stream<Ch, Traits, E> customized;
+    public:
+        typedef std::basic_string<Ch, Traits, Alloc> internal_type;
+        typedef E external_type;
+
+        explicit stream_translator(std::locale loc = std::locale())
+            : m_loc(loc)
+        {}
+
+        boost::optional<E> get_value(const internal_type &v) {
+            std::basic_istringstream<Ch, Traits, Alloc> iss(v);
+            iss.imbue(m_loc);
+            E e;
+            customized::extract(iss, e);
+            if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) {
+                return boost::optional<E>();
+            }
+            return e;
+        }
+        boost::optional<internal_type> put_value(const E &v) {
+            std::basic_ostringstream<Ch, Traits, Alloc> oss;
+            oss.imbue(m_loc);
+            customized::insert(oss, v);
+            if(oss) {
+                return oss.str();
+            }
+            return boost::optional<internal_type>();
+        }
+
+    private:
+        std::locale m_loc;
+    };
+
+    // This is the default translator when basic_string is the internal type.
+    // Unless the external type is also basic_string, in which case
+    // id_translator takes over.
+    template <typename Ch, typename Traits, typename Alloc, typename E>
+    struct translator_between<std::basic_string<Ch, Traits, Alloc>, E>
+    {
+        typedef stream_translator<Ch, Traits, Alloc, E> type;
+    };
+
+}}
+
+#endif
diff --git a/include/boost/property_tree/string_path.hpp b/include/boost/property_tree/string_path.hpp
new file mode 100644
index 0000000..3ddcfb2
--- /dev/null
+++ b/include/boost/property_tree/string_path.hpp
@@ -0,0 +1,278 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_STRING_PATH_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_STRING_PATH_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+#include <boost/property_tree/id_translator.hpp>
+#include <boost/property_tree/exceptions.hpp>
+#include <boost/property_tree/detail/ptree_utils.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/optional.hpp>
+#include <boost/throw_exception.hpp>
+#include <algorithm>
+#include <string>
+#include <iterator>
+
+namespace boost { namespace property_tree
+{
+    namespace detail
+    {
+        template <typename Sequence, typename Iterator>
+        void append_and_preserve_iter(Sequence &s, const Sequence &r,
+                                      Iterator &, std::forward_iterator_tag)
+        {
+            // Here we boldly assume that anything that is not random-access
+            // preserves validity. This is valid for the STL sequences.
+            s.insert(s.end(), r.begin(), r.end());
+        }
+        template <typename Sequence, typename Iterator>
+        void append_and_preserve_iter(Sequence &s, const Sequence &r,
+                                      Iterator &it,
+                                      std::random_access_iterator_tag)
+        {
+            // Convert the iterator to an index, and later back.
+            typename std::iterator_traits<Iterator>::difference_type idx =
+                it - s.begin();
+            s.insert(s.end(), r.begin(), r.end());
+            it = s.begin() + idx;
+        }
+
+        template <typename Sequence>
+        inline std::string dump_sequence(const Sequence &)
+        {
+            return "<undumpable sequence>";
+        }
+        inline std::string dump_sequence(const std::string &s)
+        {
+            return s;
+        }
+#ifndef BOOST_NO_STD_WSTRING
+        inline std::string dump_sequence(const std::wstring &s)
+        {
+            return narrow<std::string>(s.c_str());
+        }
+#endif
+    }
+
+    /// Default path class. A path is a sequence of values. Groups of values
+    /// are separated by the separator value, which defaults to '.' cast to
+    /// the sequence's value type. The group of values is then passed to the
+    /// translator to get a key.
+    ///
+    /// If instantiated with std::string and id_translator\<std::string\>,
+    /// it accepts paths of the form "one.two.three.four".
+    ///
+    /// @tparam String Any Sequence. If the sequence does not support random-
+    ///                access iteration, concatenation of paths assumes that
+    ///                insertions at the end preserve iterator validity.
+    /// @tparam Translator A translator with internal_type == String.
+    template <typename String, typename Translator>
+    class string_path
+    {
+        BOOST_STATIC_ASSERT((is_same<String,
+                                   typename Translator::internal_type>::value));
+    public:
+        typedef typename Translator::external_type key_type;
+        typedef typename String::value_type char_type;
+
+        /// Create an empty path.
+        explicit string_path(char_type separator = char_type('.'));
+        /// Create a path by parsing the given string.
+        /// @param value A sequence, possibly with separators, that describes
+        ///              the path, e.g. "one.two.three".
+        /// @param separator The separator used in parsing. Defaults to '.'.
+        /// @param tr The translator used by this path to convert the individual
+        ///           parts to keys.
+        string_path(const String &value, char_type separator = char_type('.'),
+                    Translator tr = Translator());
+        /// Create a path by parsing the given string.
+        /// @param value A zero-terminated array of values. Only use if zero-
+        ///              termination makes sense for your type, and your
+        ///              sequence supports construction from it. Intended for
+        ///              string literals.
+        /// @param separator The separator used in parsing. Defaults to '.'.
+        /// @param tr The translator used by this path to convert the individual
+        ///           parts to keys.
+        string_path(const char_type *value,
+                    char_type separator = char_type('.'),
+                    Translator tr = Translator());
+
+        // Default copying doesn't do the right thing with the iterator
+        string_path(const string_path &o);
+        string_path& operator =(const string_path &o);
+
+        /// Take a single element off the path at the front and return it.
+        key_type reduce();
+
+        /// Test if the path is empty.
+        bool empty() const;
+
+        /// Test if the path contains a single element, i.e. no separators.
+        bool single() const;
+
+        /// Get the separator used by this path.
+        char_type separator() const { return m_separator; }
+
+        std::string dump() const {
+            return detail::dump_sequence(m_value);
+        }
+
+        /// Append a second path to this one.
+        /// @pre o's separator is the same as this one's, or o has no separators
+        string_path& operator /=(const string_path &o) {
+            // If it's single, there's no separator. This allows to do
+            // p /= "piece";
+            // even for non-default separators.
+            BOOST_ASSERT((m_separator == o.m_separator
+                          || o.empty()
+                          || o.single())
+                         && "Incompatible paths.");
+            if(!o.empty()) {
+                String sub;
+                if(!this->empty()) {
+                    sub.push_back(m_separator);
+                }
+                sub.insert(sub.end(), o.cstart(), o.m_value.end());
+                detail::append_and_preserve_iter(m_value, sub, m_start,
+                    typename std::iterator_traits<s_iter>::iterator_category());
+            }
+            return *this;
+        }
+
+    private:
+        typedef typename String::iterator s_iter;
+        typedef typename String::const_iterator s_c_iter;
+        String m_value;
+        char_type m_separator;
+        Translator m_tr;
+        s_iter m_start;
+        s_c_iter cstart() const { return m_start; }
+    };
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>::string_path(char_type separator)
+        : m_separator(separator), m_start(m_value.begin())
+    {}
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>::string_path(const String &value,
+                                                 char_type separator,
+                                                 Translator tr)
+        : m_value(value), m_separator(separator),
+          m_tr(tr), m_start(m_value.begin())
+    {}
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>::string_path(const char_type *value,
+                                                 char_type separator,
+                                                 Translator tr)
+        : m_value(value), m_separator(separator),
+          m_tr(tr), m_start(m_value.begin())
+    {}
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>::string_path(const string_path &o)
+        : m_value(o.m_value), m_separator(o.m_separator),
+          m_tr(o.m_tr), m_start(m_value.begin())
+    {
+        std::advance(m_start, std::distance(o.m_value.begin(), o.cstart()));
+    }
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>&
+    string_path<String, Translator>::operator =(const string_path &o)
+    {
+        m_value = o.m_value;
+        m_separator = o.m_separator;
+        m_tr = o.m_tr;
+        m_start = m_value.begin();
+        std::advance(m_start, std::distance(o.m_value.begin(), o.cstart()));
+        return *this;
+    }
+
+    template <typename String, typename Translator>
+    typename Translator::external_type string_path<String, Translator>::reduce()
+    {
+        BOOST_ASSERT(!empty() && "Reducing empty path");
+
+        s_iter next_sep = std::find(m_start, m_value.end(), m_separator);
+        String part(m_start, next_sep);
+        m_start = next_sep;
+        if(!empty()) {
+          // Unless we're at the end, skip the separator we found.
+          ++m_start;
+        }
+
+        if(optional<key_type> key = m_tr.get_value(part)) {
+            return *key;
+        }
+        BOOST_PROPERTY_TREE_THROW(ptree_bad_path("Path syntax error", *this));
+    }
+
+    template <typename String, typename Translator> inline
+    bool string_path<String, Translator>::empty() const
+    {
+        return m_start == m_value.end();
+    }
+
+    template <typename String, typename Translator> inline
+    bool string_path<String, Translator>::single() const
+    {
+        return std::find(static_cast<s_c_iter>(m_start),
+                         m_value.end(), m_separator)
+            == m_value.end();
+    }
+
+    // By default, this is the path for strings. You can override this by
+    // specializing path_of for a more specific form of std::basic_string.
+    template <typename Ch, typename Traits, typename Alloc>
+    struct path_of< std::basic_string<Ch, Traits, Alloc> >
+    {
+        typedef std::basic_string<Ch, Traits, Alloc> _string;
+        typedef string_path< _string, id_translator<_string> > type;
+    };
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator> operator /(
+                                  string_path<String, Translator> p1,
+                                  const string_path<String, Translator> &p2)
+    {
+        p1 /= p2;
+        return p1;
+    }
+
+    // These shouldn't be necessary, but GCC won't find the one above.
+    template <typename String, typename Translator> inline
+    string_path<String, Translator> operator /(
+                                  string_path<String, Translator> p1,
+                                  const typename String::value_type *p2)
+    {
+        p1 /= p2;
+        return p1;
+    }
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator> operator /(
+                                  const typename String::value_type *p1,
+                                  const string_path<String, Translator> &p2)
+    {
+        string_path<String, Translator> t(p1);
+        t /= p2;
+        return t;
+    }
+
+}}
+
+#endif
diff --git a/include/boost/property_tree/xml_parser.hpp b/include/boost/property_tree/xml_parser.hpp
new file mode 100644
index 0000000..0544c55
--- /dev/null
+++ b/include/boost/property_tree/xml_parser.hpp
@@ -0,0 +1,152 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// Distributed under the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/detail/xml_parser_write.hpp>
+#include <boost/property_tree/detail/xml_parser_error.hpp>
+#include <boost/property_tree/detail/xml_parser_writer_settings.hpp>
+#include <boost/property_tree/detail/xml_parser_flags.hpp>
+#include <boost/property_tree/detail/xml_parser_read_rapidxml.hpp>
+
+#include <fstream>
+#include <string>
+#include <locale>
+
+namespace boost { namespace property_tree { namespace xml_parser
+{
+
+    /**
+     * Reads XML from an input stream and translates it to property tree.
+     * @note Clears existing contents of property tree.  In case of error the
+     *       property tree unmodified.
+     * @note XML attributes are placed under keys named @c \<xmlattr\>.
+     * @throw xml_parser_error In case of error deserializing the property tree.
+     * @param stream Stream from which to read in the property tree.
+     * @param[out] pt The property tree to populate.
+     * @param flags Flags controlling the behaviour of the parser.
+     *              The following flags are supported:
+     * @li @c no_concat_text -- Prevents concatenation of text nodes into
+     *                          datastring of property tree.  Puts them in
+     *                          separate @c \<xmltext\> strings instead.
+     * @li @c no_comments -- Skip XML comments.
+     * @li @c trim_whitespace -- Trim leading and trailing whitespace from text,
+     *                           and collapse sequences of whitespace.
+     */
+    template<class Ptree>
+    void read_xml(std::basic_istream<
+                      typename Ptree::key_type::value_type
+                  > &stream,
+                  Ptree &pt,
+                  int flags = 0)
+    {
+        read_xml_internal(stream, pt, flags, std::string());
+    }
+
+    /**
+     * Reads XML from a file using the given locale and translates it to
+     * property tree.
+     * @note Clears existing contents of property tree.  In case of error the
+     *       property tree unmodified.
+     * @note XML attributes are placed under keys named @c \<xmlattr\>.
+     * @throw xml_parser_error In case of error deserializing the property tree.
+     * @param filename The file from which to read in the property tree.
+     * @param[out] pt The property tree to populate.
+     * @param flags Flags controlling the bahviour of the parser.
+     *              The following flags are supported:
+     * @li @c no_concat_text -- Prevents concatenation of text nodes into
+     *                          datastring of property tree.  Puts them in
+     *                          separate @c \<xmltext\> strings instead.
+     * @li @c no_comments -- Skip XML comments.
+     * @param loc The locale to use when reading in the file contents.
+     */
+    template<class Ptree>
+    void read_xml(const std::string &filename,
+                  Ptree &pt,
+                  int flags = 0,
+                  const std::locale &loc = std::locale())
+    {
+        BOOST_ASSERT(validate_flags(flags));
+        std::basic_ifstream<typename Ptree::key_type::value_type>
+            stream(filename.c_str());
+        if (!stream)
+            BOOST_PROPERTY_TREE_THROW(xml_parser_error(
+                "cannot open file", filename, 0));
+        stream.imbue(loc);
+        read_xml_internal(stream, pt, flags, filename);
+    }
+
+    /**
+     * Translates the property tree to XML and writes it the given output
+     * stream.
+     * @throw xml_parser_error In case of error translating the property tree to
+     *                         XML or writing to the output stream.
+     * @param stream The stream to which to write the XML representation of the 
+     *               property tree.
+     * @param pt The property tree to tranlsate to XML and output.
+     * @param settings The settings to use when writing out the property tree as
+     *                 XML.
+     */
+    template<class Ptree>
+    void write_xml(std::basic_ostream<
+                       typename Ptree::key_type::value_type
+                   > &stream,
+                   const Ptree &pt,
+                   const xml_writer_settings<
+                       typename Ptree::key_type
+                   > & settings = xml_writer_settings<
+                                    typename Ptree::key_type>() )
+    {
+        write_xml_internal(stream, pt, std::string(), settings);
+    }
+
+    /**
+     * Translates the property tree to XML and writes it the given file.
+     * @throw xml_parser_error In case of error translating the property tree to
+     *                         XML or writing to the output stream.
+     * @param filename The file to which to write the XML representation of the 
+     *                 property tree.
+     * @param pt The property tree to tranlsate to XML and output.
+     * @param loc The locale to use when writing the output to file.
+     * @param settings The settings to use when writing out the property tree as
+     *                 XML.
+     */
+    template<class Ptree>
+    void write_xml(const std::string &filename,
+                   const Ptree &pt,
+                   const std::locale &loc = std::locale(),
+                   const xml_writer_settings<
+                       typename Ptree::key_type
+                   > & settings = xml_writer_settings<typename Ptree::key_type>())
+    {
+        std::basic_ofstream<typename Ptree::key_type::value_type>
+            stream(filename.c_str());
+        if (!stream)
+            BOOST_PROPERTY_TREE_THROW(xml_parser_error(
+                "cannot open file", filename, 0));
+        stream.imbue(loc);
+        write_xml_internal(stream, pt, filename, settings);
+    }
+
+} } }
+
+namespace boost { namespace property_tree
+{
+    using xml_parser::read_xml;
+    using xml_parser::write_xml;
+    using xml_parser::xml_parser_error;
+
+    using xml_parser::xml_writer_settings;
+    using xml_parser::xml_writer_make_settings;
+} }
+
+#endif
