diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..dcda121
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,17 @@
+LOG_TO_ANDROID_LOGCAT := true
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= tinyxml2.cpp
+
+LOCAL_MODULE:=libtinyxml2
+LOCAL_MODULE_TAGS := optional
+
+ifeq ($(LOG_TO_ANDROID_LOGCAT),true)
+LOCAL_CFLAGS+= -DDEBUG -DANDROID_NDK
+LOCAL_SHARED_LIBRARIES+= libcutils
+endif
+
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/MODULE_LICENSE_BSD_LIKE b/MODULE_LICENSE_BSD_LIKE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD_LIKE
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
new file mode 100644
index 0000000..1972e1c
--- /dev/null
+++ b/tinyxml2.cpp
@@ -0,0 +1,2021 @@
+/*
+Original code by Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+#include "tinyxml2.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <new>
+#include <cstddef>
+
+#include <fcntl.h>
+using namespace tinyxml2;
+
+static const char LINE_FEED                = (char)0x0a;            // all line endings are normalized to LF
+static const char LF = LINE_FEED;
+static const char CARRIAGE_RETURN        = (char)0x0d;            // CR gets filtered out
+static const char CR = CARRIAGE_RETURN;
+static const char SINGLE_QUOTE            = '\'';
+static const char DOUBLE_QUOTE            = '\"';
+
+// Bunch of unicode info at:
+//        http://www.unicode.org/faq/utf_bom.html
+//    ef bb bf (Microsoft "lead bytes") - designates UTF-8
+
+static const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+
+#define DELETE_NODE( node )    {            \
+    if ( node ) {                        \
+        MemPool* pool = node->memPool;    \
+        node->~XMLNode();                \
+        pool->Free( node );                \
+    }                                    \
+}
+#define DELETE_ATTRIBUTE( attrib ) {        \
+    if ( attrib ) {                            \
+        MemPool* pool = attrib->memPool;    \
+        attrib->~XMLAttribute();            \
+        pool->Free( attrib );                \
+    }                                        \
+}
+
+struct Entity {
+    const char* pattern;
+    int length;
+    char value;
+};
+
+static const int NUM_ENTITIES = 5;
+static const Entity entities[NUM_ENTITIES] =
+{
+    { "quot", 4,    DOUBLE_QUOTE },
+    { "amp", 3,        '&'  },
+    { "apos", 4,    SINGLE_QUOTE },
+    { "lt",    2,         '<'     },
+    { "gt",    2,        '>'     }
+};
+
+
+StrPair::~StrPair()
+{
+    Reset();
+}
+
+
+void StrPair::Reset()
+{
+    if ( flags & NEEDS_DELETE ) {
+        delete [] start;
+    }
+    flags = 0;
+    start = 0;
+    end = 0;
+}
+
+
+void StrPair::SetStr( const char* str, int flags )
+{
+    Reset();
+    size_t len = strlen( str );
+    start = new char[ len+1 ];
+    memcpy( start, str, len+1 );
+    end = start + len;
+    this->flags = flags | NEEDS_DELETE;
+}
+
+
+char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
+{
+    TIXMLASSERT( endTag && *endTag );
+
+    char* start = p;    // fixme: hides a member
+    char  endChar = *endTag;
+    size_t length = strlen( endTag );
+
+    // Inner loop of text parsing.
+    while ( *p ) {
+        if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
+            Set( start, p, strFlags );
+            return p + length;
+        }
+        ++p;
+    }
+    return 0;
+}
+
+
+char* StrPair::ParseName( char* p )
+{
+    char* start = p;
+
+    if ( !start || !(*start) ) {
+        return 0;
+    }
+
+    if ( !XMLUtil::IsAlpha( *p ) ) {
+        return 0;
+    }
+
+    while( *p && (
+               XMLUtil::IsAlphaNum( (unsigned char) *p )
+            || *p == '_'
+            || *p == '-'
+            || *p == '.'
+            || *p == ':' ))
+    {
+        ++p;
+    }
+
+    if ( p > start ) {
+        Set( start, p, 0 );
+        return p;
+    }
+    return 0;
+}
+
+
+
+const char* StrPair::GetStr()
+{
+    if ( flags & NEEDS_FLUSH ) {
+        *end = 0;
+        flags ^= NEEDS_FLUSH;
+
+        if ( flags ) {
+            char* p = start;    // the read pointer
+            char* q = start;    // the write pointer
+
+            while( p < end ) {
+                if ( (flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) {
+                    // CR-LF pair becomes LF
+                    // CR alone becomes LF
+                    // LF-CR becomes LF
+                    if ( *(p+1) == LF ) {
+                        p += 2;
+                    }
+                    else {
+                        ++p;
+                    }
+                    *q++ = LF;
+                }
+                else if ( (flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) {
+                    if ( *(p+1) == CR ) {
+                        p += 2;
+                    }
+                    else {
+                        ++p;
+                    }
+                    *q++ = LF;
+                }
+                else if ( (flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) {
+                    // Entities handled by tinyXML2:
+                    // - special entities in the entity table [in/out]
+                    // - numeric character reference [in]
+                    //   &#20013; or &#x4e2d;
+
+                    if ( *(p+1) == '#' ) {
+                        char buf[10] = { 0 };
+                        int len;
+                        p = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );
+                        for( int i=0; i<len; ++i ) {
+                            *q++ = buf[i];
+                        }
+                        TIXMLASSERT( q <= p );
+                    }
+                    else {
+                        int i=0;
+                        for(; i<NUM_ENTITIES; ++i ) {
+                            if (    strncmp( p+1, entities[i].pattern, entities[i].length ) == 0
+                                 && *(p+entities[i].length+1) == ';' )
+                            {
+                                // Found an entity convert;
+                                *q = entities[i].value;
+                                ++q;
+                                p += entities[i].length + 2;
+                                break;
+                            }
+                        }
+                        if ( i == NUM_ENTITIES ) {
+                            // fixme: treat as error?
+                            ++p;
+                            ++q;
+                        }
+                    }
+                }
+                else {
+                    *q = *p;
+                    ++p;
+                    ++q;
+                }
+            }
+            *q = 0;
+        }
+        flags = (flags & NEEDS_DELETE);
+    }
+    return start;
+}
+
+
+
+
+// --------- XMLUtil ----------- //
+
+const char* XMLUtil::ReadBOM( const char* p, bool* bom )
+{
+    *bom = false;
+    const unsigned char* pu = reinterpret_cast<const unsigned char*>(p);
+    // Check for BOM:
+    if (    *(pu+0) == TIXML_UTF_LEAD_0
+         && *(pu+1) == TIXML_UTF_LEAD_1
+         && *(pu+2) == TIXML_UTF_LEAD_2 )
+    {
+        *bom = true;
+        p += 3;
+    }
+    return p;
+}
+
+
+void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
+{
+    const unsigned long BYTE_MASK = 0xBF;
+    const unsigned long BYTE_MARK = 0x80;
+    const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+    if (input < 0x80)
+        *length = 1;
+    else if ( input < 0x800 )
+        *length = 2;
+    else if ( input < 0x10000 )
+        *length = 3;
+    else if ( input < 0x200000 )
+        *length = 4;
+    else
+        { *length = 0; return; }    // This code won't covert this correctly anyway.
+
+    output += *length;
+
+    // Scary scary fall throughs.
+    switch (*length)
+    {
+        case 4:
+            --output;
+            *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+            input >>= 6;
+        case 3:
+            --output;
+            *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+            input >>= 6;
+        case 2:
+            --output;
+            *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+            input >>= 6;
+        case 1:
+            --output;
+            *output = (char)(input | FIRST_BYTE_MARK[*length]);
+    }
+}
+
+
+const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
+{
+    // Presume an entity, and pull it out.
+    *length = 0;
+
+    if ( *(p+1) == '#' && *(p+2) )
+    {
+        unsigned long ucs = 0;
+        ptrdiff_t delta = 0;
+        unsigned mult = 1;
+
+        if ( *(p+2) == 'x' )
+        {
+            // Hexadecimal.
+            if ( !*(p+3) ) return 0;
+
+            const char* q = p+3;
+            q = strchr( q, ';' );
+
+            if ( !q || !*q ) return 0;
+
+            delta = q-p;
+            --q;
+
+            while ( *q != 'x' )
+            {
+                if ( *q >= '0' && *q <= '9' )
+                    ucs += mult * (*q - '0');
+                else if ( *q >= 'a' && *q <= 'f' )
+                    ucs += mult * (*q - 'a' + 10);
+                else if ( *q >= 'A' && *q <= 'F' )
+                    ucs += mult * (*q - 'A' + 10 );
+                else
+                    return 0;
+                mult *= 16;
+                --q;
+            }
+        }
+        else
+        {
+            // Decimal.
+            if ( !*(p+2) ) return 0;
+
+            const char* q = p+2;
+            q = strchr( q, ';' );
+
+            if ( !q || !*q ) return 0;
+
+            delta = q-p;
+            --q;
+
+            while ( *q != '#' )
+            {
+                if ( *q >= '0' && *q <= '9' )
+                    ucs += mult * (*q - '0');
+                else
+                    return 0;
+                mult *= 10;
+                --q;
+            }
+        }
+        // convert the UCS to UTF-8
+        ConvertUTF32ToUTF8( ucs, value, length );
+        return p + delta + 1;
+    }
+    return p+1;
+}
+
+
+void XMLUtil::ToStr( int v, char* buffer, int bufferSize )
+{
+    TIXML_SNPRINTF( buffer, bufferSize, "%d", v );
+}
+
+
+void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize )
+{
+    TIXML_SNPRINTF( buffer, bufferSize, "%u", v );
+}
+
+
+void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
+{
+    TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 );
+}
+
+
+void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
+{
+    TIXML_SNPRINTF( buffer, bufferSize, "%f", v );
+}
+
+
+void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
+{
+    TIXML_SNPRINTF( buffer, bufferSize, "%f", v );
+}
+
+
+bool XMLUtil::ToInt( const char* str, int* value )
+{
+    if ( TIXML_SSCANF( str, "%d", value ) == 1 )
+        return true;
+    return false;
+}
+
+bool XMLUtil::ToUnsigned( const char* str, unsigned *value )
+{
+    if ( TIXML_SSCANF( str, "%u", value ) == 1 )
+        return true;
+    return false;
+}
+
+bool XMLUtil::ToBool( const char* str, bool* value )
+{
+    int ival = 0;
+    if ( ToInt( str, &ival )) {
+        *value = (ival==0) ? false : true;
+        return true;
+    }
+    if ( StringEqual( str, "true" ) ) {
+        *value = true;
+        return true;
+    }
+    else if ( StringEqual( str, "false" ) ) {
+        *value = false;
+        return true;
+    }
+    return false;
+}
+
+
+bool XMLUtil::ToFloat( const char* str, float* value )
+{
+    if ( TIXML_SSCANF( str, "%f", value ) == 1 ) {
+        return true;
+    }
+    return false;
+}
+
+bool XMLUtil::ToDouble( const char* str, double* value )
+{
+    if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) {
+        return true;
+    }
+    return false;
+}
+
+
+char* XMLDocument::Identify( char* p, XMLNode** node )
+{
+    XMLNode* returnNode = 0;
+    char* start = p;
+    p = XMLUtil::SkipWhiteSpace( p );
+    if( !p || !*p )
+    {
+        return p;
+    }
+
+    // What is this thing?
+    // - Elements start with a letter or underscore, but xml is reserved.
+    // - Comments: <!--
+    // - Decleration: <?
+    // - Everthing else is unknown to tinyxml.
+    //
+
+    static const char* xmlHeader        = { "<?" };
+    static const char* commentHeader    = { "<!--" };
+    static const char* dtdHeader        = { "<!" };
+    static const char* cdataHeader        = { "<![CDATA[" };
+    static const char* elementHeader    = { "<" };    // and a header for everything else; check last.
+
+    static const int xmlHeaderLen        = 2;
+    static const int commentHeaderLen    = 4;
+    static const int dtdHeaderLen        = 2;
+    static const int cdataHeaderLen        = 9;
+    static const int elementHeaderLen    = 1;
+
+#if defined(_MSC_VER)
+#pragma warning ( push )
+#pragma warning ( disable : 4127 )
+#endif
+    TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) );        // use same memory pool
+    TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) );    // use same memory pool
+#if defined(_MSC_VER)
+#pragma warning (pop)
+#endif
+    if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
+        returnNode = new (commentPool.Alloc()) XMLDeclaration( this );
+        returnNode->memPool = &commentPool;
+        p += xmlHeaderLen;
+    }
+    else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) {
+        returnNode = new (commentPool.Alloc()) XMLComment( this );
+        returnNode->memPool = &commentPool;
+        p += commentHeaderLen;
+    }
+    else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) {
+        XMLText* text = new (textPool.Alloc()) XMLText( this );
+        returnNode = text;
+        returnNode->memPool = &textPool;
+        p += cdataHeaderLen;
+        text->SetCData( true );
+    }
+    else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {
+        returnNode = new (commentPool.Alloc()) XMLUnknown( this );
+        returnNode->memPool = &commentPool;
+        p += dtdHeaderLen;
+    }
+    else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) {
+        returnNode = new (elementPool.Alloc()) XMLElement( this );
+        returnNode->memPool = &elementPool;
+        p += elementHeaderLen;
+    }
+    else {
+        returnNode = new (textPool.Alloc()) XMLText( this );
+        returnNode->memPool = &textPool;
+        p = start;    // Back it up, all the text counts.
+    }
+
+    *node = returnNode;
+    return p;
+}
+
+
+bool XMLDocument::Accept( XMLVisitor* visitor ) const
+{
+    if ( visitor->VisitEnter( *this ) )
+    {
+        for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() )
+        {
+            if ( !node->Accept( visitor ) )
+                break;
+        }
+    }
+    return visitor->VisitExit( *this );
+}
+
+
+// --------- XMLNode ----------- //
+
+XMLNode::XMLNode( XMLDocument* doc ) :
+    document( doc ),
+    parent( 0 ),
+    firstChild( 0 ), lastChild( 0 ),
+    prev( 0 ), next( 0 )
+{
+}
+
+
+XMLNode::~XMLNode()
+{
+    DeleteChildren();
+    if ( parent ) {
+        parent->Unlink( this );
+    }
+}
+
+
+void XMLNode::SetValue( const char* str, bool staticMem )
+{
+    if ( staticMem )
+        value.SetInternedStr( str );
+    else
+        value.SetStr( str );
+}
+
+
+void XMLNode::DeleteChildren()
+{
+    while( firstChild ) {
+        XMLNode* node = firstChild;
+        Unlink( node );
+
+        DELETE_NODE( node );
+    }
+    firstChild = lastChild = 0;
+}
+
+
+void XMLNode::Unlink( XMLNode* child )
+{
+    TIXMLASSERT( child->parent == this );
+    if ( child == firstChild )
+        firstChild = firstChild->next;
+    if ( child == lastChild )
+        lastChild = lastChild->prev;
+
+    if ( child->prev ) {
+        child->prev->next = child->next;
+    }
+    if ( child->next ) {
+        child->next->prev = child->prev;
+    }
+    child->parent = 0;
+}
+
+
+void XMLNode::DeleteChild( XMLNode* node )
+{
+    TIXMLASSERT( node->parent == this );
+    DELETE_NODE( node );
+}
+
+
+XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
+{
+    if ( lastChild ) {
+        TIXMLASSERT( firstChild );
+        TIXMLASSERT( lastChild->next == 0 );
+        lastChild->next = addThis;
+        addThis->prev = lastChild;
+        lastChild = addThis;
+
+        addThis->next = 0;
+    }
+    else {
+        TIXMLASSERT( firstChild == 0 );
+        firstChild = lastChild = addThis;
+
+        addThis->prev = 0;
+        addThis->next = 0;
+    }
+    addThis->parent = this;
+    return addThis;
+}
+
+
+XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
+{
+    if ( firstChild ) {
+        TIXMLASSERT( lastChild );
+        TIXMLASSERT( firstChild->prev == 0 );
+
+        firstChild->prev = addThis;
+        addThis->next = firstChild;
+        firstChild = addThis;
+
+        addThis->prev = 0;
+    }
+    else {
+        TIXMLASSERT( lastChild == 0 );
+        firstChild = lastChild = addThis;
+
+        addThis->prev = 0;
+        addThis->next = 0;
+    }
+    addThis->parent = this;
+    return addThis;
+}
+
+
+XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
+{
+    TIXMLASSERT( afterThis->parent == this );
+    if ( afterThis->parent != this )
+        return 0;
+
+    if ( afterThis->next == 0 ) {
+        // The last node or the only node.
+        return InsertEndChild( addThis );
+    }
+    addThis->prev = afterThis;
+    addThis->next = afterThis->next;
+    afterThis->next->prev = addThis;
+    afterThis->next = addThis;
+    addThis->parent = this;
+    return addThis;
+}
+
+
+
+
+const XMLElement* XMLNode::FirstChildElement( const char* value ) const
+{
+    for( XMLNode* node=firstChild; node; node=node->next ) {
+        XMLElement* element = node->ToElement();
+        if ( element ) {
+            if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) {
+                return element;
+            }
+        }
+    }
+    return 0;
+}
+
+
+const XMLElement* XMLNode::LastChildElement( const char* value ) const
+{
+    for( XMLNode* node=lastChild; node; node=node->prev ) {
+        XMLElement* element = node->ToElement();
+        if ( element ) {
+            if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) {
+                return element;
+            }
+        }
+    }
+    return 0;
+}
+
+
+const XMLElement* XMLNode::NextSiblingElement( const char* value ) const
+{
+    for( XMLNode* element=this->next; element; element = element->next ) {
+        if (    element->ToElement()
+             && (!value || XMLUtil::StringEqual( value, element->Value() )))
+        {
+            return element->ToElement();
+        }
+    }
+    return 0;
+}
+
+
+const XMLElement* XMLNode::PreviousSiblingElement( const char* value ) const
+{
+    for( XMLNode* element=this->prev; element; element = element->prev ) {
+        if (    element->ToElement()
+             && (!value || XMLUtil::StringEqual( value, element->Value() )))
+        {
+            return element->ToElement();
+        }
+    }
+    return 0;
+}
+
+
+char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
+{
+    // This is a recursive method, but thinking about it "at the current level"
+    // it is a pretty simple flat list:
+    //        <foo/>
+    //        <!-- comment -->
+    //
+    // With a special case:
+    //        <foo>
+    //        </foo>
+    //        <!-- comment -->
+    //
+    // Where the closing element (/foo) *must* be the next thing after the opening
+    // element, and the names must match. BUT the tricky bit is that the closing
+    // element will be read by the child.
+    //
+    // 'endTag' is the end tag for this node, it is returned by a call to a child.
+    // 'parentEnd' is the end tag for the parent, which is filled in and returned.
+
+    while( p && *p ) {
+        XMLNode* node = 0;
+
+        p = document->Identify( p, &node );
+        if ( p == 0 || node == 0 ) {
+            break;
+        }
+
+        StrPair endTag;
+        p = node->ParseDeep( p, &endTag );
+        if ( !p ) {
+            DELETE_NODE( node );
+            node = 0;
+            if ( !document->Error() ) {
+                document->SetError( XML_ERROR_PARSING, 0, 0 );
+            }
+            break;
+        }
+
+        // We read the end tag. Return it to the parent.
+        if ( node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) {
+            if ( parentEnd ) {
+                *parentEnd = static_cast<XMLElement*>(node)->value;
+            }
+            DELETE_NODE( node );
+            return p;
+        }
+
+        // Handle an end tag returned to this level.
+        // And handle a bunch of annoying errors.
+        XMLElement* ele = node->ToElement();
+        if ( ele ) {
+            if ( endTag.Empty() && ele->ClosingType() == XMLElement::OPEN ) {
+                document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
+                p = 0;
+            }
+            else if ( !endTag.Empty() && ele->ClosingType() != XMLElement::OPEN ) {
+                document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
+                p = 0;
+            }
+            else if ( !endTag.Empty() ) {
+                if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() )) {
+                    document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
+                    p = 0;
+                }
+            }
+        }
+        if ( p == 0 ) {
+            DELETE_NODE( node );
+            node = 0;
+        }
+        if ( node ) {
+            this->InsertEndChild( node );
+        }
+    }
+    return 0;
+}
+
+// --------- XMLText ---------- //
+char* XMLText::ParseDeep( char* p, StrPair* )
+{
+    const char* start = p;
+    if ( this->CData() ) {
+        p = value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION );
+        if ( !p ) {
+            document->SetError( XML_ERROR_PARSING_CDATA, start, 0 );
+        }
+        return p;
+    }
+    else {
+        p = value.ParseText( p, "<", document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES );
+        if ( !p ) {
+            document->SetError( XML_ERROR_PARSING_TEXT, start, 0 );
+        }
+        if ( p && *p ) {
+            return p-1;
+        }
+    }
+    return 0;
+}
+
+
+XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const
+{
+    if ( !doc ) {
+        doc = document;
+    }
+    XMLText* text = doc->NewText( Value() );    // fixme: this will always allocate memory. Intern?
+    text->SetCData( this->CData() );
+    return text;
+}
+
+
+bool XMLText::ShallowEqual( const XMLNode* compare ) const
+{
+    return ( compare->ToText() && XMLUtil::StringEqual( compare->ToText()->Value(), Value() ));
+}
+
+
+bool XMLText::Accept( XMLVisitor* visitor ) const
+{
+    return visitor->Visit( *this );
+}
+
+
+// --------- XMLComment ---------- //
+
+XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc )
+{
+}
+
+
+XMLComment::~XMLComment()
+{
+    //printf( "~XMLComment\n" );
+}
+
+
+char* XMLComment::ParseDeep( char* p, StrPair* )
+{
+    // Comment parses as text.
+    const char* start = p;
+    p = value.ParseText( p, "-->", StrPair::COMMENT );
+    if ( p == 0 ) {
+        document->SetError( XML_ERROR_PARSING_COMMENT, start, 0 );
+    }
+    return p;
+}
+
+
+XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const
+{
+    if ( !doc ) {
+        doc = document;
+    }
+    XMLComment* comment = doc->NewComment( Value() );    // fixme: this will always allocate memory. Intern?
+    return comment;
+}
+
+
+bool XMLComment::ShallowEqual( const XMLNode* compare ) const
+{
+    return ( compare->ToComment() && XMLUtil::StringEqual( compare->ToComment()->Value(), Value() ));
+}
+
+
+bool XMLComment::Accept( XMLVisitor* visitor ) const
+{
+    return visitor->Visit( *this );
+}
+
+
+// --------- XMLDeclaration ---------- //
+
+XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc )
+{
+}
+
+
+XMLDeclaration::~XMLDeclaration()
+{
+    //printf( "~XMLDeclaration\n" );
+}
+
+
+char* XMLDeclaration::ParseDeep( char* p, StrPair* )
+{
+    // Declaration parses as text.
+    const char* start = p;
+    p = value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION );
+    if ( p == 0 ) {
+        document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0 );
+    }
+    return p;
+}
+
+
+XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const
+{
+    if ( !doc ) {
+        doc = document;
+    }
+    XMLDeclaration* dec = doc->NewDeclaration( Value() );    // fixme: this will always allocate memory. Intern?
+    return dec;
+}
+
+
+bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const
+{
+    return ( compare->ToDeclaration() && XMLUtil::StringEqual( compare->ToDeclaration()->Value(), Value() ));
+}
+
+
+
+bool XMLDeclaration::Accept( XMLVisitor* visitor ) const
+{
+    return visitor->Visit( *this );
+}
+
+// --------- XMLUnknown ---------- //
+
+XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc )
+{
+}
+
+
+XMLUnknown::~XMLUnknown()
+{
+}
+
+
+char* XMLUnknown::ParseDeep( char* p, StrPair* )
+{
+    // Unknown parses as text.
+    const char* start = p;
+
+    p = value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION );
+    if ( !p ) {
+        document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0 );
+    }
+    return p;
+}
+
+
+XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const
+{
+    if ( !doc ) {
+        doc = document;
+    }
+    XMLUnknown* text = doc->NewUnknown( Value() );    // fixme: this will always allocate memory. Intern?
+    return text;
+}
+
+
+bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const
+{
+    return ( compare->ToUnknown() && XMLUtil::StringEqual( compare->ToUnknown()->Value(), Value() ));
+}
+
+
+bool XMLUnknown::Accept( XMLVisitor* visitor ) const
+{
+    return visitor->Visit( *this );
+}
+
+// --------- XMLAttribute ---------- //
+char* XMLAttribute::ParseDeep( char* p, bool processEntities )
+{
+    // Parse using the name rules: bug fix, was using ParseText before
+    p = name.ParseName( p );
+    if ( !p || !*p ) return 0;
+
+    // Skip white space before =
+    p = XMLUtil::SkipWhiteSpace( p );
+    if ( !p || *p != '=' ) return 0;
+
+    ++p;    // move up to opening quote
+    p = XMLUtil::SkipWhiteSpace( p );
+    if ( *p != '\"' && *p != '\'' ) return 0;
+
+    char endTag[2] = { *p, 0 };
+    ++p;    // move past opening quote
+
+    p = value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES );
+    return p;
+}
+
+
+void XMLAttribute::SetName( const char* n )
+{
+    name.SetStr( n );
+}
+
+
+int XMLAttribute::QueryIntValue( int* value ) const
+{
+    if ( XMLUtil::ToInt( Value(), value ))
+        return XML_NO_ERROR;
+    return XML_WRONG_ATTRIBUTE_TYPE;
+}
+
+
+int XMLAttribute::QueryUnsignedValue( unsigned int* value ) const
+{
+    if ( XMLUtil::ToUnsigned( Value(), value ))
+        return XML_NO_ERROR;
+    return XML_WRONG_ATTRIBUTE_TYPE;
+}
+
+
+int XMLAttribute::QueryBoolValue( bool* value ) const
+{
+    if ( XMLUtil::ToBool( Value(), value )) {
+        return XML_NO_ERROR;
+    }
+    return XML_WRONG_ATTRIBUTE_TYPE;
+}
+
+
+int XMLAttribute::QueryFloatValue( float* value ) const
+{
+    if ( XMLUtil::ToFloat( Value(), value ))
+        return XML_NO_ERROR;
+    return XML_WRONG_ATTRIBUTE_TYPE;
+}
+
+
+int XMLAttribute::QueryDoubleValue( double* value ) const
+{
+    if ( XMLUtil::ToDouble( Value(), value ))
+        return XML_NO_ERROR;
+    return XML_WRONG_ATTRIBUTE_TYPE;
+}
+
+
+void XMLAttribute::SetAttribute( const char* v )
+{
+    value.SetStr( v );
+}
+
+
+void XMLAttribute::SetAttribute( int v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    value.SetStr( buf );
+}
+
+
+void XMLAttribute::SetAttribute( unsigned v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    value.SetStr( buf );
+}
+
+
+void XMLAttribute::SetAttribute( bool v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    value.SetStr( buf );
+}
+
+void XMLAttribute::SetAttribute( double v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    value.SetStr( buf );
+}
+
+void XMLAttribute::SetAttribute( float v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    value.SetStr( buf );
+}
+
+
+// --------- XMLElement ---------- //
+XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),
+    closingType( 0 ),
+    rootAttribute( 0 )
+{
+}
+
+
+XMLElement::~XMLElement()
+{
+    while( rootAttribute ) {
+        XMLAttribute* next = rootAttribute->next;
+        DELETE_ATTRIBUTE( rootAttribute );
+        rootAttribute = next;
+    }
+}
+
+
+XMLAttribute* XMLElement::FindAttribute( const char* name )
+{
+    XMLAttribute* a = 0;
+    for( a=rootAttribute; a; a = a->next ) {
+        if ( XMLUtil::StringEqual( a->Name(), name ) )
+            return a;
+    }
+    return 0;
+}
+
+
+const XMLAttribute* XMLElement::FindAttribute( const char* name ) const
+{
+    XMLAttribute* a = 0;
+    for( a=rootAttribute; a; a = a->next ) {
+        if ( XMLUtil::StringEqual( a->Name(), name ) )
+            return a;
+    }
+    return 0;
+}
+
+
+const char* XMLElement::Attribute( const char* name, const char* value ) const
+{
+    const XMLAttribute* a = FindAttribute( name );
+    if ( !a )
+        return 0;
+    if ( !value || XMLUtil::StringEqual( a->Value(), value ))
+        return a->Value();
+    return 0;
+}
+
+
+const char* XMLElement::GetText() const
+{
+    if ( FirstChild() && FirstChild()->ToText() ) {
+        return FirstChild()->ToText()->Value();
+    }
+    return 0;
+}
+
+
+int XMLElement::QueryIntText( int* _value ) const
+{
+    if ( FirstChild() && FirstChild()->ToText() ) {
+        const char* t = FirstChild()->ToText()->Value();
+        if ( XMLUtil::ToInt( t, _value ) ) {
+            return XML_SUCCESS;
+        }
+        return XML_CAN_NOT_CONVERT_TEXT;
+    }
+    return XML_NO_TEXT_NODE;
+}
+
+
+int XMLElement::QueryUnsignedText( unsigned* _value ) const
+{
+    if ( FirstChild() && FirstChild()->ToText() ) {
+        const char* t = FirstChild()->ToText()->Value();
+        if ( XMLUtil::ToUnsigned( t, _value ) ) {
+            return XML_SUCCESS;
+        }
+        return XML_CAN_NOT_CONVERT_TEXT;
+    }
+    return XML_NO_TEXT_NODE;
+}
+
+
+int XMLElement::QueryBoolText( bool* _value ) const
+{
+    if ( FirstChild() && FirstChild()->ToText() ) {
+        const char* t = FirstChild()->ToText()->Value();
+        if ( XMLUtil::ToBool( t, _value ) ) {
+            return XML_SUCCESS;
+        }
+        return XML_CAN_NOT_CONVERT_TEXT;
+    }
+    return XML_NO_TEXT_NODE;
+}
+
+
+int XMLElement::QueryDoubleText( double* _value ) const
+{
+    if ( FirstChild() && FirstChild()->ToText() ) {
+        const char* t = FirstChild()->ToText()->Value();
+        if ( XMLUtil::ToDouble( t, _value ) ) {
+            return XML_SUCCESS;
+        }
+        return XML_CAN_NOT_CONVERT_TEXT;
+    }
+    return XML_NO_TEXT_NODE;
+}
+
+
+int XMLElement::QueryFloatText( float* _value ) const
+{
+    if ( FirstChild() && FirstChild()->ToText() ) {
+        const char* t = FirstChild()->ToText()->Value();
+        if ( XMLUtil::ToFloat( t, _value ) ) {
+            return XML_SUCCESS;
+        }
+        return XML_CAN_NOT_CONVERT_TEXT;
+    }
+    return XML_NO_TEXT_NODE;
+}
+
+
+
+XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
+{
+    XMLAttribute* last = 0;
+    XMLAttribute* attrib = 0;
+    for( attrib = rootAttribute;
+         attrib;
+         last = attrib, attrib = attrib->next )
+    {
+        if ( XMLUtil::StringEqual( attrib->Name(), name ) ) {
+            break;
+        }
+    }
+    if ( !attrib ) {
+        attrib = new (document->attributePool.Alloc() ) XMLAttribute();
+        attrib->memPool = &document->attributePool;
+        if ( last ) {
+            last->next = attrib;
+        }
+        else {
+            rootAttribute = attrib;
+        }
+        attrib->SetName( name );
+    }
+    return attrib;
+}
+
+
+void XMLElement::DeleteAttribute( const char* name )
+{
+    XMLAttribute* prev = 0;
+    for( XMLAttribute* a=rootAttribute; a; a=a->next ) {
+        if ( XMLUtil::StringEqual( name, a->Name() ) ) {
+            if ( prev ) {
+                prev->next = a->next;
+            }
+            else {
+                rootAttribute = a->next;
+            }
+            DELETE_ATTRIBUTE( a );
+            break;
+        }
+        prev = a;
+    }
+}
+
+
+char* XMLElement::ParseAttributes( char* p )
+{
+    const char* start = p;
+    XMLAttribute* prevAttribute = 0;
+
+    // Read the attributes.
+    while( p ) {
+        p = XMLUtil::SkipWhiteSpace( p );
+        if ( !p || !(*p) ) {
+            document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() );
+            return 0;
+        }
+
+        // attribute.
+        if ( XMLUtil::IsAlpha( *p ) ) {
+            XMLAttribute* attrib = new (document->attributePool.Alloc() ) XMLAttribute();
+            attrib->memPool = &document->attributePool;
+
+            p = attrib->ParseDeep( p, document->ProcessEntities() );
+            if ( !p || Attribute( attrib->Name() ) ) {
+                DELETE_ATTRIBUTE( attrib );
+                document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p );
+                return 0;
+            }
+            // There is a minor bug here: if the attribute in the source xml
+            // document is duplicated, it will not be detected and the
+            // attribute will be doubly added. However, tracking the 'prevAttribute'
+            // avoids re-scanning the attribute list. Preferring performance for
+            // now, may reconsider in the future.
+            if ( prevAttribute ) {
+                prevAttribute->next = attrib;
+            }
+            else {
+                rootAttribute = attrib;
+            }
+            prevAttribute = attrib;
+        }
+        // end of the tag
+        else if ( *p == '/' && *(p+1) == '>' ) {
+            closingType = CLOSED;
+            return p+2;    // done; sealed element.
+        }
+        // end of the tag
+        else if ( *p == '>' ) {
+            ++p;
+            break;
+        }
+        else {
+            document->SetError( XML_ERROR_PARSING_ELEMENT, start, p );
+            return 0;
+        }
+    }
+    return p;
+}
+
+
+//
+//    <ele></ele>
+//    <ele>foo<b>bar</b></ele>
+//
+char* XMLElement::ParseDeep( char* p, StrPair* strPair )
+{
+    // Read the element name.
+    p = XMLUtil::SkipWhiteSpace( p );
+    if ( !p ) return 0;
+
+    // The closing element is the </element> form. It is
+    // parsed just like a regular element then deleted from
+    // the DOM.
+    if ( *p == '/' ) {
+        closingType = CLOSING;
+        ++p;
+    }
+
+    p = value.ParseName( p );
+    if ( value.Empty() ) return 0;
+
+    p = ParseAttributes( p );
+    if ( !p || !*p || closingType )
+        return p;
+
+    p = XMLNode::ParseDeep( p, strPair );
+    return p;
+}
+
+
+
+XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const
+{
+    if ( !doc ) {
+        doc = document;
+    }
+    XMLElement* element = doc->NewElement( Value() );                    // fixme: this will always allocate memory. Intern?
+    for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) {
+        element->SetAttribute( a->Name(), a->Value() );                    // fixme: this will always allocate memory. Intern?
+    }
+    return element;
+}
+
+
+bool XMLElement::ShallowEqual( const XMLNode* compare ) const
+{
+    const XMLElement* other = compare->ToElement();
+    if ( other && XMLUtil::StringEqual( other->Value(), Value() )) {
+
+        const XMLAttribute* a=FirstAttribute();
+        const XMLAttribute* b=other->FirstAttribute();
+
+        while ( a && b ) {
+            if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) {
+                return false;
+            }
+            a = a->Next();
+            b = b->Next();
+        }
+        if ( a || b ) {
+            // different count
+            return false;
+        }
+        return true;
+    }
+    return false;
+}
+
+
+bool XMLElement::Accept( XMLVisitor* visitor ) const
+{
+    if ( visitor->VisitEnter( *this, rootAttribute ) )
+    {
+        for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() )
+        {
+            if ( !node->Accept( visitor ) )
+                break;
+        }
+    }
+    return visitor->VisitExit( *this );
+}
+
+
+// --------- XMLDocument ----------- //
+XMLDocument::XMLDocument( bool _processEntities ) :
+    XMLNode( 0 ),
+    writeBOM( false ),
+    processEntities( _processEntities ),
+    errorID( 0 ),
+    errorStr1( 0 ),
+    errorStr2( 0 ),
+    charBuffer( 0 )
+{
+    document = this;    // avoid warning about 'this' in initializer list
+}
+
+
+XMLDocument::~XMLDocument()
+{
+    DeleteChildren();
+    delete [] charBuffer;
+
+#if 0
+    textPool.Trace( "text" );
+    elementPool.Trace( "element" );
+    commentPool.Trace( "comment" );
+    attributePool.Trace( "attribute" );
+#endif
+
+    TIXMLASSERT( textPool.CurrentAllocs() == 0 );
+    TIXMLASSERT( elementPool.CurrentAllocs() == 0 );
+    TIXMLASSERT( commentPool.CurrentAllocs() == 0 );
+    TIXMLASSERT( attributePool.CurrentAllocs() == 0 );
+}
+
+
+void XMLDocument::InitDocument()
+{
+    errorID = XML_NO_ERROR;
+    errorStr1 = 0;
+    errorStr2 = 0;
+
+    delete [] charBuffer;
+    charBuffer = 0;
+
+}
+
+
+XMLElement* XMLDocument::NewElement( const char* name )
+{
+    XMLElement* ele = new (elementPool.Alloc()) XMLElement( this );
+    ele->memPool = &elementPool;
+    ele->SetName( name );
+    return ele;
+}
+
+
+XMLComment* XMLDocument::NewComment( const char* str )
+{
+    XMLComment* comment = new (commentPool.Alloc()) XMLComment( this );
+    comment->memPool = &commentPool;
+    comment->SetValue( str );
+    return comment;
+}
+
+
+XMLText* XMLDocument::NewText( const char* str )
+{
+    XMLText* text = new (textPool.Alloc()) XMLText( this );
+    text->memPool = &textPool;
+    text->SetValue( str );
+    return text;
+}
+
+
+XMLDeclaration* XMLDocument::NewDeclaration( const char* str )
+{
+    XMLDeclaration* dec = new (commentPool.Alloc()) XMLDeclaration( this );
+    dec->memPool = &commentPool;
+    dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" );
+    return dec;
+}
+
+
+XMLUnknown* XMLDocument::NewUnknown( const char* str )
+{
+    XMLUnknown* unk = new (commentPool.Alloc()) XMLUnknown( this );
+    unk->memPool = &commentPool;
+    unk->SetValue( str );
+    return unk;
+}
+
+
+int XMLDocument::LoadFile( const char* filename )
+{
+    DeleteChildren();
+    InitDocument();
+
+#if defined(_MSC_VER)
+#pragma warning ( push )
+#pragma warning ( disable : 4996 )        // Fail to see a compelling reason why this should be deprecated.
+#endif
+    FILE* fp = fopen( filename, "rb" );
+#if defined(_MSC_VER)
+#pragma warning ( pop )
+#endif
+    if ( !fp ) {
+        SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 );
+        return errorID;
+    }
+    LoadFile( fp );
+    fclose( fp );
+    return errorID;
+}
+
+
+int XMLDocument::LoadFile( FILE* fp )
+{
+    DeleteChildren();
+    InitDocument();
+
+    fseek( fp, 0, SEEK_END );
+    unsigned size = ftell( fp );
+    fseek( fp, 0, SEEK_SET );
+
+    if ( size == 0 ) {
+        return errorID;
+    }
+
+    charBuffer = new char[size+1];
+    size_t read = fread( charBuffer, 1, size, fp );
+    if ( read != size ) {
+        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
+        return errorID;
+    }
+
+    charBuffer[size] = 0;
+
+    const char* p = charBuffer;
+    p = XMLUtil::SkipWhiteSpace( p );
+    p = XMLUtil::ReadBOM( p, &writeBOM );
+    if ( !p || !*p ) {
+        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
+        return errorID;
+    }
+
+    ParseDeep( charBuffer + (p-charBuffer), 0 );
+    return errorID;
+}
+
+
+int XMLDocument::SaveFile( const char* filename )
+{
+#if defined(_MSC_VER)
+#pragma warning ( push )
+#pragma warning ( disable : 4996 )        // Fail to see a compelling reason why this should be deprecated.
+#endif
+    int fd = open(filename, O_RDWR|O_CREAT, 0644);
+    FILE* fp = fdopen(fd, "w");
+    //FILE* fp = fopen( filename, "w" );
+#if defined(_MSC_VER)
+#pragma warning ( pop )
+#endif
+    if ( !fp ) {
+        SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 );
+        return errorID;
+    }
+    SaveFile(fp);
+    fclose( fp );
+    return errorID;
+}
+
+
+int XMLDocument::SaveFile( FILE* fp )
+{
+    XMLPrinter stream( fp );
+    Print( &stream );
+    return errorID;
+}
+
+
+int XMLDocument::Parse( const char* p )
+{
+    DeleteChildren();
+    InitDocument();
+
+    if ( !p || !*p ) {
+        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
+        return errorID;
+    }
+    p = XMLUtil::SkipWhiteSpace( p );
+    p = XMLUtil::ReadBOM( p, &writeBOM );
+    if ( !p || !*p ) {
+        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
+        return errorID;
+    }
+
+    size_t len = strlen( p );
+    charBuffer = new char[ len+1 ];
+    memcpy( charBuffer, p, len+1 );
+
+
+    ParseDeep( charBuffer, 0 );
+    return errorID;
+}
+
+
+void XMLDocument::Print( XMLPrinter* streamer )
+{
+    XMLPrinter stdStreamer( stdout );
+    if ( !streamer )
+        streamer = &stdStreamer;
+    Accept( streamer );
+}
+
+
+void XMLDocument::SetError( int error, const char* str1, const char* str2 )
+{
+    errorID = error;
+    errorStr1 = str1;
+    errorStr2 = str2;
+}
+
+
+void XMLDocument::PrintError() const
+{
+    if ( errorID ) {
+        static const int LEN = 20;
+        char buf1[LEN] = { 0 };
+        char buf2[LEN] = { 0 };
+
+        if ( errorStr1 ) {
+            TIXML_SNPRINTF( buf1, LEN, "%s", errorStr1 );
+        }
+        if ( errorStr2 ) {
+            TIXML_SNPRINTF( buf2, LEN, "%s", errorStr2 );
+        }
+
+        printf( "XMLDocument error id=%d str1=%s str2=%s\n",
+                errorID, buf1, buf2 );
+    }
+}
+
+
+XMLPrinter::XMLPrinter( FILE* file, bool compact ) :
+    elementJustOpened( false ),
+    firstElement( true ),
+    fp( file ),
+    depth( 0 ),
+    textDepth( -1 ),
+    processEntities( true ),
+    compactMode( compact )
+{
+    for( int i=0; i<ENTITY_RANGE; ++i ) {
+        entityFlag[i] = false;
+        restrictedEntityFlag[i] = false;
+    }
+    for( int i=0; i<NUM_ENTITIES; ++i ) {
+        TIXMLASSERT( entities[i].value < ENTITY_RANGE );
+        if ( entities[i].value < ENTITY_RANGE ) {
+            entityFlag[ (int)entities[i].value ] = true;
+        }
+    }
+    restrictedEntityFlag[(int)'&'] = true;
+    restrictedEntityFlag[(int)'<'] = true;
+    restrictedEntityFlag[(int)'>'] = true;    // not required, but consistency is nice
+    buffer.Push( 0 );
+}
+
+
+void XMLPrinter::Print( const char* format, ... )
+{
+    va_list     va;
+    va_start( va, format );
+
+    if ( fp ) {
+        vfprintf( fp, format, va );
+    }
+    else {
+        // This seems brutally complex. Haven't figured out a better
+        // way on windows.
+        #ifdef _MSC_VER
+            int len = -1;
+            int expand = 1000;
+            while ( len < 0 ) {
+                len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), _TRUNCATE, format, va );
+                if ( len < 0 ) {
+                    expand *= 3/2;
+                    accumulator.PushArr( expand );
+                }
+            }
+            char* p = buffer.PushArr( len ) - 1;
+            memcpy( p, accumulator.Mem(), len+1 );
+        #else
+            int len = vsnprintf( 0, 0, format, va );
+            // Close out and re-start the va-args
+            va_end( va );
+            va_start( va, format );
+            char* p = buffer.PushArr( len ) - 1;
+            vsnprintf( p, len+1, format, va );
+        #endif
+    }
+    va_end( va );
+}
+
+
+void XMLPrinter::PrintSpace( int depth )
+{
+    for( int i=0; i<depth; ++i ) {
+        Print( "    " );
+    }
+}
+
+
+void XMLPrinter::PrintString( const char* p, bool restricted )
+{
+    // Look for runs of bytes between entities to print.
+    const char* q = p;
+    const bool* flag = restricted ? restrictedEntityFlag : entityFlag;
+
+    if ( processEntities ) {
+        while ( *q ) {
+            // Remember, char is sometimes signed. (How many times has that bitten me?)
+            if ( *q > 0 && *q < ENTITY_RANGE ) {
+                // Check for entities. If one is found, flush
+                // the stream up until the entity, write the
+                // entity, and keep looking.
+                if ( flag[(unsigned)(*q)] ) {
+                    while ( p < q ) {
+                        Print( "%c", *p );
+                        ++p;
+                    }
+                    for( int i=0; i<NUM_ENTITIES; ++i ) {
+                        if ( entities[i].value == *q ) {
+                            Print( "&%s;", entities[i].pattern );
+                            break;
+                        }
+                    }
+                    ++p;
+                }
+            }
+            ++q;
+        }
+    }
+    // Flush the remaining string. This will be the entire
+    // string if an entity wasn't found.
+    if ( !processEntities || (q-p > 0) ) {
+        Print( "%s", p );
+    }
+}
+
+
+void XMLPrinter::PushHeader( bool writeBOM, bool writeDec )
+{
+    static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
+    if ( writeBOM ) {
+        Print( "%s", bom );
+    }
+    if ( writeDec ) {
+        PushDeclaration( "xml version=\"1.0\"" );
+    }
+}
+
+
+void XMLPrinter::OpenElement( const char* name )
+{
+    if ( elementJustOpened ) {
+        SealElement();
+    }
+    stack.Push( name );
+
+    if ( textDepth < 0 && !firstElement && !compactMode ) {
+        Print( "\n" );
+        PrintSpace( depth );
+    }
+
+    Print( "<%s", name );
+    elementJustOpened = true;
+    firstElement = false;
+    ++depth;
+}
+
+
+void XMLPrinter::PushAttribute( const char* name, const char* value )
+{
+    TIXMLASSERT( elementJustOpened );
+    Print( " %s=\"", name );
+    PrintString( value, false );
+    Print( "\"" );
+}
+
+
+void XMLPrinter::PushAttribute( const char* name, int v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    PushAttribute( name, buf );
+}
+
+
+void XMLPrinter::PushAttribute( const char* name, unsigned v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    PushAttribute( name, buf );
+}
+
+
+void XMLPrinter::PushAttribute( const char* name, bool v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    PushAttribute( name, buf );
+}
+
+
+void XMLPrinter::PushAttribute( const char* name, double v )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( v, buf, BUF_SIZE );
+    PushAttribute( name, buf );
+}
+
+
+void XMLPrinter::CloseElement()
+{
+    --depth;
+    const char* name = stack.Pop();
+
+    if ( elementJustOpened ) {
+        Print( "/>" );
+    }
+    else {
+        if ( textDepth < 0 && !compactMode) {
+            Print( "\n" );
+            PrintSpace( depth );
+        }
+        Print( "</%s>", name );
+    }
+
+    if ( textDepth == depth )
+        textDepth = -1;
+    if ( depth == 0 && !compactMode)
+        Print( "\n" );
+    elementJustOpened = false;
+}
+
+
+void XMLPrinter::SealElement()
+{
+    elementJustOpened = false;
+    Print( ">" );
+}
+
+
+void XMLPrinter::PushText( const char* text, bool cdata )
+{
+    textDepth = depth-1;
+
+    if ( elementJustOpened ) {
+        SealElement();
+    }
+    if ( cdata ) {
+        Print( "<![CDATA[" );
+        Print( "%s", text );
+        Print( "]]>" );
+    }
+    else {
+        PrintString( text, true );
+    }
+}
+
+void XMLPrinter::PushText( int value )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( value, buf, BUF_SIZE );
+    PushText( buf, false );
+}
+
+
+void XMLPrinter::PushText( unsigned value )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( value, buf, BUF_SIZE );
+    PushText( buf, false );
+}
+
+
+void XMLPrinter::PushText( bool value )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( value, buf, BUF_SIZE );
+    PushText( buf, false );
+}
+
+
+void XMLPrinter::PushText( float value )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( value, buf, BUF_SIZE );
+    PushText( buf, false );
+}
+
+
+void XMLPrinter::PushText( double value )
+{
+    char buf[BUF_SIZE];
+    XMLUtil::ToStr( value, buf, BUF_SIZE );
+    PushText( buf, false );
+}
+
+
+void XMLPrinter::PushComment( const char* comment )
+{
+    if ( elementJustOpened ) {
+        SealElement();
+    }
+    if ( textDepth < 0 && !firstElement && !compactMode) {
+        Print( "\n" );
+        PrintSpace( depth );
+    }
+    firstElement = false;
+    Print( "<!--%s-->", comment );
+}
+
+
+void XMLPrinter::PushDeclaration( const char* value )
+{
+    if ( elementJustOpened ) {
+        SealElement();
+    }
+    if ( textDepth < 0 && !firstElement && !compactMode) {
+        Print( "\n" );
+        PrintSpace( depth );
+    }
+    firstElement = false;
+    Print( "<?%s?>", value );
+}
+
+
+void XMLPrinter::PushUnknown( const char* value )
+{
+    if ( elementJustOpened ) {
+        SealElement();
+    }
+    if ( textDepth < 0 && !firstElement && !compactMode) {
+        Print( "\n" );
+        PrintSpace( depth );
+    }
+    firstElement = false;
+    Print( "<!%s>", value );
+}
+
+
+bool XMLPrinter::VisitEnter( const XMLDocument& doc )
+{
+    processEntities = doc.ProcessEntities();
+    if ( doc.HasBOM() ) {
+        PushHeader( true, false );
+    }
+    return true;
+}
+
+
+bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute )
+{
+    OpenElement( element.Name() );
+    while ( attribute ) {
+        PushAttribute( attribute->Name(), attribute->Value() );
+        attribute = attribute->Next();
+    }
+    return true;
+}
+
+
+bool XMLPrinter::VisitExit( const XMLElement& )
+{
+    CloseElement();
+    return true;
+}
+
+
+bool XMLPrinter::Visit( const XMLText& text )
+{
+    PushText( text.Value(), text.CData() );
+    return true;
+}
+
+
+bool XMLPrinter::Visit( const XMLComment& comment )
+{
+    PushComment( comment.Value() );
+    return true;
+}
+
+bool XMLPrinter::Visit( const XMLDeclaration& declaration )
+{
+    PushDeclaration( declaration.Value() );
+    return true;
+}
+
+
+bool XMLPrinter::Visit( const XMLUnknown& unknown )
+{
+    PushUnknown( unknown.Value() );
+    return true;
+}
diff --git a/tinyxml2.h b/tinyxml2.h
new file mode 100644
index 0000000..8cabd0c
--- /dev/null
+++ b/tinyxml2.h
@@ -0,0 +1,1480 @@
+/*
+Original code by Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#ifndef TINYXML2_INCLUDED
+#define TINYXML2_INCLUDED
+
+#include <cctype>
+#include <climits>
+#include <cstdio>
+#include <cstring>
+//#include <cstdarg>
+#include <stdarg.h>
+/*
+   TODO: intern strings instead of allocation.
+*/
+/*
+    gcc: g++ -Wall tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
+*/
+
+#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
+    #ifndef DEBUG
+        #define DEBUG
+    #endif
+#endif
+
+
+#if defined(DEBUG)
+        #if defined(_MSC_VER)
+                #define TIXMLASSERT( x )           if ( !(x)) { __debugbreak(); } //if ( !(x)) WinDebugBreak()
+        #elif defined (ANDROID_NDK)
+                #include <android/log.h>
+                #define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
+        #else
+                #include <assert.h>
+                #define TIXMLASSERT                assert
+        #endif
+#else
+        #define TIXMLASSERT( x )           {}
+#endif
+
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+    // Microsoft visual studio, version 2005 and higher.
+    /*int _snprintf_s(
+       char *buffer,
+       size_t sizeOfBuffer,
+       size_t count,
+       const char *format [,
+          argument] ...
+    );*/
+    inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) {
+        va_list va;
+        va_start( va, format );
+        int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
+        va_end( va );
+        return result;
+    }
+    #define TIXML_SSCANF   sscanf_s
+#else
+    // GCC version 3 and higher
+    //#warning( "Using sn* functions." )
+    #define TIXML_SNPRINTF snprintf
+    #define TIXML_SSCANF   sscanf
+#endif
+
+static const int TIXML2_MAJOR_VERSION = 1;
+static const int TIXML2_MINOR_VERSION = 0;
+static const int TIXML2_PATCH_VERSION = 6;
+
+namespace tinyxml2
+{
+class XMLDocument;
+class XMLElement;
+class XMLAttribute;
+class XMLComment;
+class XMLNode;
+class XMLText;
+class XMLDeclaration;
+class XMLUnknown;
+
+class XMLPrinter;
+
+/*
+    A class that wraps strings. Normally stores the start and end
+    pointers into the XML file itself, and will apply normalization
+    and entity translation if actually read. Can also store (and memory
+    manage) a traditional char[]
+*/
+class StrPair
+{
+public:
+    enum {
+        NEEDS_ENTITY_PROCESSING            = 0x01,
+        NEEDS_NEWLINE_NORMALIZATION        = 0x02,
+
+        TEXT_ELEMENT        = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
+        TEXT_ELEMENT_LEAVE_ENTITIES        = NEEDS_NEWLINE_NORMALIZATION,
+        ATTRIBUTE_NAME        = 0,
+        ATTRIBUTE_VALUE        = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
+        ATTRIBUTE_VALUE_LEAVE_ENTITIES        = NEEDS_NEWLINE_NORMALIZATION,
+        COMMENT                = NEEDS_NEWLINE_NORMALIZATION
+    };
+
+    StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
+    ~StrPair();
+
+    void Set( char* _start, char* _end, int _flags ) {
+        Reset();
+        this->start = _start; this->end = _end; this->flags = _flags | NEEDS_FLUSH;
+    }
+    const char* GetStr();
+    bool Empty() const { return start == end; }
+
+    void SetInternedStr( const char* str ) { Reset(); this->start = const_cast<char*>(str); }
+    void SetStr( const char* str, int flags=0 );
+
+    char* ParseText( char* in, const char* endTag, int strFlags );
+    char* ParseName( char* in );
+
+
+private:
+    void Reset();
+
+    enum {
+        NEEDS_FLUSH = 0x100,
+        NEEDS_DELETE = 0x200
+    };
+
+    // After parsing, if *end != 0, it can be set to zero.
+    int flags;
+    char* start;
+    char* end;
+};
+
+
+/*
+    A dynamic array of Plain Old Data. Doesn't support constructors, etc.
+    Has a small initial memory pool, so that low or no usage will not
+    cause a call to new/delete
+*/
+template <class T, int INIT>
+class DynArray
+{
+public:
+    DynArray< T, INIT >()
+    {
+        mem = pool;
+        allocated = INIT;
+        size = 0;
+    }
+    ~DynArray()
+    {
+        if ( mem != pool ) {
+            delete [] mem;
+        }
+    }
+    void Push( T t )
+    {
+        EnsureCapacity( size+1 );
+        mem[size++] = t;
+    }
+
+    T* PushArr( int count )
+    {
+        EnsureCapacity( size+count );
+        T* ret = &mem[size];
+        size += count;
+        return ret;
+    }
+    T Pop() {
+        return mem[--size];
+    }
+    void PopArr( int count )
+    {
+        TIXMLASSERT( size >= count );
+        size -= count;
+    }
+
+    bool Empty() const                    { return size == 0; }
+    T& operator[](int i)                { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
+    const T& operator[](int i) const    { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
+    int Size() const                    { return size; }
+    int Capacity() const                { return allocated; }
+    const T* Mem() const                { return mem; }
+    T* Mem()                            { return mem; }
+
+
+private:
+    void EnsureCapacity( int cap ) {
+        if ( cap > allocated ) {
+            int newAllocated = cap * 2;
+            T* newMem = new T[newAllocated];
+            memcpy( newMem, mem, sizeof(T)*size );    // warning: not using constructors, only works for PODs
+            if ( mem != pool ) delete [] mem;
+            mem = newMem;
+            allocated = newAllocated;
+        }
+    }
+
+    T* mem;
+    T pool[INIT];
+    int allocated;        // objects allocated
+    int size;            // number objects in use
+};
+
+
+/*
+    Parent virtual class of a pool for fast allocation
+    and deallocation of objects.
+*/
+class MemPool
+{
+public:
+    MemPool() {}
+    virtual ~MemPool() {}
+
+    virtual int ItemSize() const = 0;
+    virtual void* Alloc() = 0;
+    virtual void Free( void* ) = 0;
+};
+
+
+/*
+    Template child class to create pools of the correct type.
+*/
+template< int SIZE >
+class MemPoolT : public MemPool
+{
+public:
+    MemPoolT() : root(0), currentAllocs(0), nAllocs(0), maxAllocs(0)    {}
+    ~MemPoolT() {
+        // Delete the blocks.
+        for( int i=0; i<blockPtrs.Size(); ++i ) {
+            delete blockPtrs[i];
+        }
+    }
+
+    virtual int ItemSize() const    { return SIZE; }
+    int CurrentAllocs() const        { return currentAllocs; }
+
+    virtual void* Alloc() {
+        if ( !root ) {
+            // Need a new block.
+            Block* block = new Block();
+            blockPtrs.Push( block );
+
+            for( int i=0; i<COUNT-1; ++i ) {
+                block->chunk[i].next = &block->chunk[i+1];
+            }
+            block->chunk[COUNT-1].next = 0;
+            root = block->chunk;
+        }
+        void* result = root;
+        root = root->next;
+
+        ++currentAllocs;
+        if ( currentAllocs > maxAllocs ) maxAllocs = currentAllocs;
+        nAllocs++;
+        return result;
+    }
+    virtual void Free( void* mem ) {
+        if ( !mem ) return;
+        --currentAllocs;
+        Chunk* chunk = (Chunk*)mem;
+        memset( chunk, 0xfe, sizeof(Chunk) );
+        chunk->next = root;
+        root = chunk;
+    }
+    void Trace( const char* name ) {
+        printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
+                 name, maxAllocs, maxAllocs*SIZE/1024, currentAllocs, SIZE, nAllocs, blockPtrs.Size() );
+    }
+
+private:
+    enum { COUNT = 1024/SIZE };
+    union Chunk {
+        Chunk* next;
+        char mem[SIZE];
+    };
+    struct Block {
+        Chunk chunk[COUNT];
+    };
+    DynArray< Block*, 10 > blockPtrs;
+    Chunk* root;
+
+    int currentAllocs;
+    int nAllocs;
+    int maxAllocs;
+};
+
+
+
+/**
+    Implements the interface to the "Visitor pattern" (see the Accept() method.)
+    If you call the Accept() method, it requires being passed a XMLVisitor
+    class to handle callbacks. For nodes that contain other nodes (Document, Element)
+    you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
+    are simply called with Visit().
+
+    If you return 'true' from a Visit method, recursive parsing will continue. If you return
+    false, <b>no children of this node or its sibilings</b> will be visited.
+
+    All flavors of Visit methods have a default implementation that returns 'true' (continue
+    visiting). You need to only override methods that are interesting to you.
+
+    Generally Accept() is called on the TiXmlDocument, although all nodes support visiting.
+
+    You should never change the document from a callback.
+
+    @sa XMLNode::Accept()
+*/
+class XMLVisitor
+{
+public:
+    virtual ~XMLVisitor() {}
+
+    /// Visit a document.
+    virtual bool VisitEnter( const XMLDocument& /*doc*/ )            { return true; }
+    /// Visit a document.
+    virtual bool VisitExit( const XMLDocument& /*doc*/ )            { return true; }
+
+    /// Visit an element.
+    virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )    { return true; }
+    /// Visit an element.
+    virtual bool VisitExit( const XMLElement& /*element*/ )            { return true; }
+
+    /// Visit a declaration.
+    virtual bool Visit( const XMLDeclaration& /*declaration*/ )        { return true; }
+    /// Visit a text node.
+    virtual bool Visit( const XMLText& /*text*/ )                    { return true; }
+    /// Visit a comment node.
+    virtual bool Visit( const XMLComment& /*comment*/ )                { return true; }
+    /// Visit an unknown node.
+    virtual bool Visit( const XMLUnknown& /*unknown*/ )                { return true; }
+};
+
+
+/*
+    Utility functionality.
+*/
+class XMLUtil
+{
+public:
+    // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
+    // correct, but simple, and usually works.
+    static const char* SkipWhiteSpace( const char* p )    { while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<const unsigned char*>(p) ) ) { ++p; } return p; }
+    static char* SkipWhiteSpace( char* p )                { while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<unsigned char*>(p) ) )        { ++p; } return p; }
+
+    inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {
+        int n = 0;
+        if ( p == q ) {
+            return true;
+        }
+        while( *p && *q && *p == *q && n<nChar ) {
+            ++p; ++q; ++n;
+        }
+        if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
+            return true;
+        }
+        return false;
+    }
+    inline static int IsUTF8Continuation( const char p ) { return p & 0x80; }
+    inline static int IsAlphaNum( unsigned char anyByte )    { return ( anyByte < 128 ) ? isalnum( anyByte ) : 1; }
+    inline static int IsAlpha( unsigned char anyByte )        { return ( anyByte < 128 ) ? isalpha( anyByte ) : 1; }
+
+    static const char* ReadBOM( const char* p, bool* hasBOM );
+    // p is the starting location,
+    // the UTF-8 value of the entity will be placed in value, and length filled in.
+    static const char* GetCharacterRef( const char* p, char* value, int* length );
+    static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+    // converts primitive types to strings
+    static void ToStr( int v, char* buffer, int bufferSize );
+    static void ToStr( unsigned v, char* buffer, int bufferSize );
+    static void ToStr( bool v, char* buffer, int bufferSize );
+    static void ToStr( float v, char* buffer, int bufferSize );
+    static void ToStr( double v, char* buffer, int bufferSize );
+
+    // converts strings to primitive types
+    static bool    ToInt( const char* str, int* value );
+    static bool ToUnsigned( const char* str, unsigned* value );
+    static bool    ToBool( const char* str, bool* value );
+    static bool    ToFloat( const char* str, float* value );
+    static bool ToDouble( const char* str, double* value );
+};
+
+
+/** XMLNode is a base class for every object that is in the
+    XML Document Object Model (DOM), except XMLAttributes.
+    Nodes have siblings, a parent, and children which can
+    be navigated. A node is always in a XMLDocument.
+    The type of a XMLNode can be queried, and it can
+    be cast to its more defined type.
+
+    A XMLDocument allocates memory for all its Nodes.
+    When the XMLDocument gets deleted, all its Nodes
+    will also be deleted.
+
+    @verbatim
+    A Document can contain:    Element    (container or leaf)
+                            Comment (leaf)
+                            Unknown (leaf)
+                            Declaration( leaf )
+
+    An Element can contain:    Element (container or leaf)
+                            Text    (leaf)
+                            Attributes (not on tree)
+                            Comment (leaf)
+                            Unknown (leaf)
+
+    @endverbatim
+*/
+class XMLNode
+{
+    friend class XMLDocument;
+    friend class XMLElement;
+public:
+
+    /// Get the XMLDocument that owns this XMLNode.
+    const XMLDocument* GetDocument() const    { return document; }
+    /// Get the XMLDocument that owns this XMLNode.
+    XMLDocument* GetDocument()                { return document; }
+
+    virtual XMLElement*        ToElement()        { return 0; }    ///< Safely cast to an Element, or null.
+    virtual XMLText*        ToText()        { return 0; }    ///< Safely cast to Text, or null.
+    virtual XMLComment*        ToComment()        { return 0; }    ///< Safely cast to a Comment, or null.
+    virtual XMLDocument*    ToDocument()    { return 0; }    ///< Safely cast to a Document, or null.
+    virtual XMLDeclaration*    ToDeclaration()    { return 0; }    ///< Safely cast to a Declaration, or null.
+    virtual XMLUnknown*        ToUnknown()        { return 0; }    ///< Safely cast to an Unknown, or null.
+
+    virtual const XMLElement*        ToElement() const        { return 0; }
+    virtual const XMLText*            ToText() const            { return 0; }
+    virtual const XMLComment*        ToComment() const        { return 0; }
+    virtual const XMLDocument*        ToDocument() const        { return 0; }
+    virtual const XMLDeclaration*    ToDeclaration() const    { return 0; }
+    virtual const XMLUnknown*        ToUnknown() const        { return 0; }
+
+    /** The meaning of 'value' changes for the specific type.
+        @verbatim
+        Document:    empty
+        Element:    name of the element
+        Comment:    the comment text
+        Unknown:    the tag contents
+        Text:        the text string
+        @endverbatim
+    */
+    const char* Value() const            { return value.GetStr(); }
+    /** Set the Value of an XML node.
+        @sa Value()
+    */
+    void SetValue( const char* val, bool staticMem=false );
+
+    /// Get the parent of this node on the DOM.
+    const XMLNode*    Parent() const            { return parent; }
+    XMLNode* Parent()                        { return parent; }
+
+    /// Returns true if this node has no children.
+    bool NoChildren() const                    { return !firstChild; }
+
+    /// Get the first child node, or null if none exists.
+    const XMLNode*  FirstChild() const        { return firstChild; }
+    XMLNode*        FirstChild()            { return firstChild; }
+    /** Get the first child element, or optionally the first child
+        element with the specified name.
+    */
+    const XMLElement* FirstChildElement( const char* value=0 ) const;
+    XMLElement* FirstChildElement( const char* _value=0 )    { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( _value )); }
+
+    /// Get the last child node, or null if none exists.
+    const XMLNode*    LastChild() const                        { return lastChild; }
+    XMLNode*        LastChild()                                { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->LastChild() ); }
+
+    /** Get the last child element or optionally the last child
+        element with the specified name.
+    */
+    const XMLElement* LastChildElement( const char* value=0 ) const;
+    XMLElement* LastChildElement( const char* _value=0 )    { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(_value) ); }
+
+    /// Get the previous (left) sibling node of this node.
+    const XMLNode*    PreviousSibling() const                    { return prev; }
+    XMLNode*    PreviousSibling()                            { return prev; }
+
+    /// Get the previous (left) sibling element of this node, with an opitionally supplied name.
+    const XMLElement*    PreviousSiblingElement( const char* value=0 ) const ;
+    XMLElement*    PreviousSiblingElement( const char* _value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( _value ) ); }
+
+    /// Get the next (right) sibling node of this node.
+    const XMLNode*    NextSibling() const                        { return next; }
+    XMLNode*    NextSibling()                                { return next; }
+
+    /// Get the next (right) sibling element of this node, with an opitionally supplied name.
+    const XMLElement*    NextSiblingElement( const char* value=0 ) const;
+     XMLElement*    NextSiblingElement( const char* _value=0 )    { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( _value ) ); }
+
+    /**
+        Add a child node as the last (right) child.
+    */
+    XMLNode* InsertEndChild( XMLNode* addThis );
+
+    XMLNode* LinkEndChild( XMLNode* addThis )    { return InsertEndChild( addThis ); }
+    /**
+        Add a child node as the first (left) child.
+    */
+    XMLNode* InsertFirstChild( XMLNode* addThis );
+    /**
+        Add a node after the specified child node.
+    */
+    XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
+
+    /**
+        Delete all the children of this node.
+    */
+    void DeleteChildren();
+
+    /**
+        Delete a child of this node.
+    */
+    void DeleteChild( XMLNode* node );
+
+    /**
+        Make a copy of this node, but not its children.
+        You may pass in a Document pointer that will be
+        the owner of the new Node. If the 'document' is
+        null, then the node returned will be allocated
+        from the current Document. (this->GetDocument())
+
+        Note: if called on a XMLDocument, this will return null.
+    */
+    virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
+
+    /**
+        Test if 2 nodes are the same, but don't test children.
+        The 2 nodes do not need to be in the same Document.
+
+        Note: if called on a XMLDocument, this will return false.
+    */
+    virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
+
+    /** Accept a hierarchical visit of the nodes in the TinyXML DOM. Every node in the
+        XML tree will be conditionally visited and the host will be called back
+        via the TiXmlVisitor interface.
+
+        This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
+        the XML for the callbacks, so the performance of TinyXML is unchanged by using this
+        interface versus any other.)
+
+        The interface has been based on ideas from:
+
+        - http://www.saxproject.org/
+        - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
+
+        Which are both good references for "visiting".
+
+        An example of using Accept():
+        @verbatim
+        TiXmlPrinter printer;
+        tinyxmlDoc.Accept( &printer );
+        const char* xmlcstr = printer.CStr();
+        @endverbatim
+    */
+    virtual bool Accept( XMLVisitor* visitor ) const = 0;
+
+    // internal
+    virtual char* ParseDeep( char*, StrPair* );
+
+protected:
+    XMLNode( XMLDocument* );
+    virtual ~XMLNode();
+    XMLNode( const XMLNode& );    // not supported
+    XMLNode& operator=( const XMLNode& );    // not supported
+
+    XMLDocument*    document;
+    XMLNode*        parent;
+    mutable StrPair    value;
+
+    XMLNode*        firstChild;
+    XMLNode*        lastChild;
+
+    XMLNode*        prev;
+    XMLNode*        next;
+
+private:
+    MemPool*        memPool;
+    void Unlink( XMLNode* child );
+};
+
+
+/** XML text.
+
+    Note that a text node can have child element nodes, for example:
+    @verbatim
+    <root>This is <b>bold</b></root>
+    @endverbatim
+
+    A text node can have 2 ways to output the next. "normal" output
+    and CDATA. It will default to the mode it was parsed from the XML file and
+    you generally want to leave it alone, but you can change the output mode with
+    SetCDATA() and query it with CDATA().
+*/
+class XMLText : public XMLNode
+{
+    friend class XMLBase;
+    friend class XMLDocument;
+public:
+    virtual bool Accept( XMLVisitor* visitor ) const;
+
+    virtual XMLText*    ToText()            { return this; }
+    virtual const XMLText*    ToText() const    { return this; }
+
+    /// Declare whether this should be CDATA or standard text.
+    void SetCData( bool _isCData )            { this->isCData = _isCData; }
+    /// Returns true if this is a CDATA text element.
+    bool CData() const                        { return isCData; }
+
+    char* ParseDeep( char*, StrPair* endTag );
+    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
+    virtual bool ShallowEqual( const XMLNode* compare ) const;
+
+
+protected:
+    XMLText( XMLDocument* doc )    : XMLNode( doc ), isCData( false )    {}
+    virtual ~XMLText()                                                {}
+    XMLText( const XMLText& );    // not supported
+    XMLText& operator=( const XMLText& );    // not supported
+
+private:
+    bool isCData;
+};
+
+
+/** An XML Comment. */
+class XMLComment : public XMLNode
+{
+    friend class XMLDocument;
+public:
+    virtual XMLComment*    ToComment()                    { return this; }
+    virtual const XMLComment* ToComment() const        { return this; }
+
+    virtual bool Accept( XMLVisitor* visitor ) const;
+
+    char* ParseDeep( char*, StrPair* endTag );
+    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
+    virtual bool ShallowEqual( const XMLNode* compare ) const;
+
+protected:
+    XMLComment( XMLDocument* doc );
+    virtual ~XMLComment();
+    XMLComment( const XMLComment& );    // not supported
+    XMLComment& operator=( const XMLComment& );    // not supported
+
+private:
+};
+
+
+/** In correct XML the declaration is the first entry in the file.
+    @verbatim
+        <?xml version="1.0" standalone="yes"?>
+    @endverbatim
+
+    TinyXML2 will happily read or write files without a declaration,
+    however.
+
+    The text of the declaration isn't interpreted. It is parsed
+    and written as a string.
+*/
+class XMLDeclaration : public XMLNode
+{
+    friend class XMLDocument;
+public:
+    virtual XMLDeclaration*    ToDeclaration()                    { return this; }
+    virtual const XMLDeclaration* ToDeclaration() const        { return this; }
+
+    virtual bool Accept( XMLVisitor* visitor ) const;
+
+    char* ParseDeep( char*, StrPair* endTag );
+    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
+    virtual bool ShallowEqual( const XMLNode* compare ) const;
+
+protected:
+    XMLDeclaration( XMLDocument* doc );
+    virtual ~XMLDeclaration();
+    XMLDeclaration( const XMLDeclaration& );    // not supported
+    XMLDeclaration& operator=( const XMLDeclaration& );    // not supported
+};
+
+
+/** Any tag that tinyXml doesn't recognize is saved as an
+    unknown. It is a tag of text, but should not be modified.
+    It will be written back to the XML, unchanged, when the file
+    is saved.
+
+    DTD tags get thrown into TiXmlUnknowns.
+*/
+class XMLUnknown : public XMLNode
+{
+    friend class XMLDocument;
+public:
+    virtual XMLUnknown*    ToUnknown()                    { return this; }
+    virtual const XMLUnknown* ToUnknown() const        { return this; }
+
+    virtual bool Accept( XMLVisitor* visitor ) const;
+
+    char* ParseDeep( char*, StrPair* endTag );
+    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
+    virtual bool ShallowEqual( const XMLNode* compare ) const;
+
+protected:
+    XMLUnknown( XMLDocument* doc );
+    virtual ~XMLUnknown();
+    XMLUnknown( const XMLUnknown& );    // not supported
+    XMLUnknown& operator=( const XMLUnknown& );    // not supported
+};
+
+
+enum {
+    XML_NO_ERROR = 0,
+    XML_SUCCESS = 0,
+
+    XML_NO_ATTRIBUTE,
+    XML_WRONG_ATTRIBUTE_TYPE,
+
+    XML_ERROR_FILE_NOT_FOUND,
+    XML_ERROR_FILE_COULD_NOT_BE_OPENED,
+    XML_ERROR_FILE_READ_ERROR,
+    XML_ERROR_ELEMENT_MISMATCH,
+    XML_ERROR_PARSING_ELEMENT,
+    XML_ERROR_PARSING_ATTRIBUTE,
+    XML_ERROR_IDENTIFYING_TAG,
+    XML_ERROR_PARSING_TEXT,
+    XML_ERROR_PARSING_CDATA,
+    XML_ERROR_PARSING_COMMENT,
+    XML_ERROR_PARSING_DECLARATION,
+    XML_ERROR_PARSING_UNKNOWN,
+    XML_ERROR_EMPTY_DOCUMENT,
+    XML_ERROR_MISMATCHED_ELEMENT,
+    XML_ERROR_PARSING,
+
+    XML_CAN_NOT_CONVERT_TEXT,
+    XML_NO_TEXT_NODE
+};
+
+
+/** An attribute is a name-value pair. Elements have an arbitrary
+    number of attributes, each with a unique name.
+
+    @note The attributes are not XMLNodes. You may only query the
+    Next() attribute in a list.
+*/
+class XMLAttribute
+{
+    friend class XMLElement;
+public:
+    const char* Name() const { return name.GetStr(); }            ///< The name of the attribute.
+    const char* Value() const { return value.GetStr(); }        ///< The value of the attribute.
+    const XMLAttribute* Next() const { return next; }            ///< The next attribute in the list.
+
+    /** IntAttribute interprets the attribute as an integer, and returns the value.
+        If the value isn't an integer, 0 will be returned. There is no error checking;
+        use QueryIntAttribute() if you need error checking.
+    */
+    int         IntValue() const                { int i=0;        QueryIntValue( &i );        return i; }
+    /// Query as an unsigned integer. See IntAttribute()
+    unsigned UnsignedValue() const            { unsigned i=0; QueryUnsignedValue( &i );    return i; }
+    /// Query as a boolean. See IntAttribute()
+    bool     BoolValue() const                { bool b=false; QueryBoolValue( &b );        return b; }
+    /// Query as a double. See IntAttribute()
+    double      DoubleValue() const            { double d=0;    QueryDoubleValue( &d );        return d; }
+    /// Query as a float. See IntAttribute()
+    float     FloatValue() const                { float f=0;    QueryFloatValue( &f );        return f; }
+
+    /** QueryIntAttribute interprets the attribute as an integer, and returns the value
+        in the provided paremeter. The function will return XML_NO_ERROR on success,
+        and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
+    */
+    int QueryIntValue( int* value ) const;
+    /// See QueryIntAttribute
+    int QueryUnsignedValue( unsigned int* value ) const;
+    /// See QueryIntAttribute
+    int QueryBoolValue( bool* value ) const;
+    /// See QueryIntAttribute
+    int QueryDoubleValue( double* value ) const;
+    /// See QueryIntAttribute
+    int QueryFloatValue( float* value ) const;
+
+    /// Set the attribute to a string value.
+    void SetAttribute( const char* value );
+    /// Set the attribute to value.
+    void SetAttribute( int value );
+    /// Set the attribute to value.
+    void SetAttribute( unsigned value );
+    /// Set the attribute to value.
+    void SetAttribute( bool value );
+    /// Set the attribute to value.
+    void SetAttribute( double value );
+    /// Set the attribute to value.
+    void SetAttribute( float value );
+
+private:
+    enum { BUF_SIZE = 200 };
+
+    XMLAttribute() : next( 0 ) {}
+    virtual ~XMLAttribute()    {}
+    XMLAttribute( const XMLAttribute& );    // not supported
+    void operator=( const XMLAttribute& );    // not supported
+    void SetName( const char* name );
+
+    char* ParseDeep( char* p, bool processEntities );
+
+    mutable StrPair name;
+    mutable StrPair value;
+    XMLAttribute* next;
+    MemPool* memPool;
+};
+
+
+/** The element is a container class. It has a value, the element name,
+    and can contain other elements, text, comments, and unknowns.
+    Elements also contain an arbitrary number of attributes.
+*/
+class XMLElement : public XMLNode
+{
+    friend class XMLBase;
+    friend class XMLDocument;
+public:
+    /// Get the name of an element (which is the Value() of the node.)
+    const char* Name() const        { return Value(); }
+    /// Set the name of the element.
+    void SetName( const char* str, bool staticMem=false )    { SetValue( str, staticMem ); }
+
+    virtual XMLElement* ToElement()                { return this; }
+    virtual const XMLElement* ToElement() const { return this; }
+    virtual bool Accept( XMLVisitor* visitor ) const;
+
+    /** Given an attribute name, Attribute() returns the value
+        for the attribute of that name, or null if none
+        exists. For example:
+
+        @verbatim
+        const char* value = ele->Attribute( "foo" );
+        @endverbatim
+
+        The 'value' parameter is normally null. However, if specified,
+        the attribute will only be returned if the 'name' and 'value'
+        match. This allow you to write code:
+
+        @verbatim
+        if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
+        @endverbatim
+
+        rather than:
+        @verbatim
+        if ( ele->Attribute( "foo" ) ) {
+            if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
+        }
+        @endverbatim
+    */
+    const char* Attribute( const char* name, const char* value=0 ) const;
+
+    /** Given an attribute name, IntAttribute() returns the value
+        of the attribute interpreted as an integer. 0 will be
+        returned if there is an error. For a method with error
+        checking, see QueryIntAttribute()
+    */
+    int         IntAttribute( const char* name ) const        { int i=0;        QueryIntAttribute( name, &i );        return i; }
+    /// See IntAttribute()
+    unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; }
+    /// See IntAttribute()
+    bool     BoolAttribute( const char* name ) const    { bool b=false; QueryBoolAttribute( name, &b );        return b; }
+    /// See IntAttribute()
+    double      DoubleAttribute( const char* name ) const    { double d=0;    QueryDoubleAttribute( name, &d );    return d; }
+    /// See IntAttribute()
+    float     FloatAttribute( const char* name ) const    { float f=0;    QueryFloatAttribute( name, &f );    return f; }
+
+    /** Given an attribute name, QueryIntAttribute() returns
+        XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
+        can't be performed, or XML_NO_ATTRIBUTE if the attribute
+        doesn't exist. If successful, the result of the conversion
+        will be written to 'value'. If not successful, nothing will
+        be written to 'value'. This allows you to provide default
+        value:
+
+        @verbatim
+        int value = 10;
+        QueryIntAttribute( "foo", &value );        // if "foo" isn't found, value will still be 10
+        @endverbatim
+    */
+    int QueryIntAttribute( const char* name, int* _value ) const                { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryIntValue( _value ); }
+    /// See QueryIntAttribute()
+    int QueryUnsignedAttribute( const char* name, unsigned int* _value ) const    { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryUnsignedValue( _value ); }
+    /// See QueryIntAttribute()
+    int QueryBoolAttribute( const char* name, bool* _value ) const                { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryBoolValue( _value ); }
+    /// See QueryIntAttribute()
+    int QueryDoubleAttribute( const char* name, double* _value ) const            { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryDoubleValue( _value ); }
+    /// See QueryIntAttribute()
+    int QueryFloatAttribute( const char* name, float* _value ) const            { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryFloatValue( _value ); }
+
+    /// Sets the named attribute to value.
+    void SetAttribute( const char* name, const char* _value )    { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); }
+    /// Sets the named attribute to value.
+    void SetAttribute( const char* name, int _value )            { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); }
+    /// Sets the named attribute to value.
+    void SetAttribute( const char* name, unsigned _value )        { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); }
+    /// Sets the named attribute to value.
+    void SetAttribute( const char* name, bool _value )            { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); }
+    /// Sets the named attribute to value.
+    void SetAttribute( const char* name, double _value )        { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); }
+
+    /**
+        Delete an attribute.
+    */
+    void DeleteAttribute( const char* name );
+
+    /// Return the first attribute in the list.
+    const XMLAttribute* FirstAttribute() const { return rootAttribute; }
+    /// Query a specific attribute in the list.
+    const XMLAttribute* FindAttribute( const char* name ) const;
+
+    /** Convenience function for easy access to the text inside an element. Although easy
+        and concise, GetText() is limited compared to getting the TiXmlText child
+        and accessing it directly.
+
+        If the first child of 'this' is a TiXmlText, the GetText()
+        returns the character string of the Text node, else null is returned.
+
+        This is a convenient method for getting the text of simple contained text:
+        @verbatim
+        <foo>This is text</foo>
+            const char* str = fooElement->GetText();
+        @endverbatim
+
+        'str' will be a pointer to "This is text".
+
+        Note that this function can be misleading. If the element foo was created from
+        this XML:
+        @verbatim
+            <foo><b>This is text</b></foo>
+        @endverbatim
+
+        then the value of str would be null. The first child node isn't a text node, it is
+        another element. From this XML:
+        @verbatim
+            <foo>This is <b>text</b></foo>
+        @endverbatim
+        GetText() will return "This is ".
+    */
+    const char* GetText() const;
+
+    /**
+        Convenience method to query the value of a child text node. This is probably best
+        shown by example. Given you have a document is this form:
+        @verbatim
+            <point>
+                <x>1</x>
+                <y>1.4</y>
+            </point>
+        @endverbatim
+
+        The QueryIntText() and similar functions provide a safe and easier way to get to the
+        "value" of x and y.
+
+        @verbatim
+            int x = 0;
+            float y = 0;    // types of x and y are contrived for example
+            const XMLElement* xElement = pointElement->FirstChildElement( "x" );
+            const XMLElement* yElement = pointElement->FirstChildElement( "y" );
+            xElement->QueryIntText( &x );
+            yElement->QueryFloatText( &y );
+        @endverbatim
+
+        @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
+                 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
+
+    */
+    int QueryIntText( int* _value ) const;
+    /// See QueryIntText()
+    int QueryUnsignedText( unsigned* _value ) const;
+    /// See QueryIntText()
+    int QueryBoolText( bool* _value ) const;
+    /// See QueryIntText()
+    int QueryDoubleText( double* _value ) const;
+    /// See QueryIntText()
+    int QueryFloatText( float* _value ) const;
+
+    // internal:
+    enum {
+        OPEN,        // <foo>
+        CLOSED,        // <foo/>
+        CLOSING        // </foo>
+    };
+    int ClosingType() const { return closingType; }
+    char* ParseDeep( char* p, StrPair* endTag );
+    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
+    virtual bool ShallowEqual( const XMLNode* compare ) const;
+
+private:
+    XMLElement( XMLDocument* doc );
+    virtual ~XMLElement();
+    XMLElement( const XMLElement& );    // not supported
+    void operator=( const XMLElement& );    // not supported
+
+    XMLAttribute* FindAttribute( const char* name );
+    XMLAttribute* FindOrCreateAttribute( const char* name );
+    //void LinkAttribute( XMLAttribute* attrib );
+    char* ParseAttributes( char* p );
+
+    int closingType;
+    // The attribute list is ordered; there is no 'lastAttribute'
+    // because the list needs to be scanned for dupes before adding
+    // a new attribute.
+    XMLAttribute* rootAttribute;
+};
+
+
+/** A Document binds together all the functionality.
+    It can be saved, loaded, and printed to the screen.
+    All Nodes are connected and allocated to a Document.
+    If the Document is deleted, all its Nodes are also deleted.
+*/
+class XMLDocument : public XMLNode
+{
+    friend class XMLElement;
+public:
+    /// constructor
+    XMLDocument( bool processEntities = true );
+    ~XMLDocument();
+
+    virtual XMLDocument* ToDocument()                { return this; }
+    virtual const XMLDocument* ToDocument() const    { return this; }
+
+    /**
+        Parse an XML file from a character string.
+        Returns XML_NO_ERROR (0) on success, or
+        an errorID.
+    */
+    int Parse( const char* xml );
+
+    /**
+        Load an XML file from disk.
+        Returns XML_NO_ERROR (0) on success, or
+        an errorID.
+    */
+    int LoadFile( const char* filename );
+
+    /**
+        Load an XML file from disk. You are responsible
+        for providing and closing the FILE*.
+
+        Returns XML_NO_ERROR (0) on success, or
+        an errorID.
+    */
+    int LoadFile( FILE* );
+
+    /**
+        Save the XML file to disk.
+        Returns XML_NO_ERROR (0) on success, or
+        an errorID.
+    */
+    int SaveFile( const char* filename );
+
+    /**
+        Save the XML file to disk. You are responsible
+        for providing and closing the FILE*.
+
+        Returns XML_NO_ERROR (0) on success, or
+        an errorID.
+    */
+    int SaveFile( FILE* );
+
+    bool ProcessEntities() const                        { return processEntities; }
+
+    /**
+        Returns true if this document has a leading Byte Order Mark of UTF8.
+    */
+    bool HasBOM() const { return writeBOM; }
+    /** Sets whether to write the BOM when writing the file.
+    */
+    void SetBOM( bool useBOM ) { writeBOM = useBOM; }
+
+    /** Return the root element of DOM. Equivalent to FirstChildElement().
+        To get the first node, use FirstChild().
+    */
+    XMLElement* RootElement()                { return FirstChildElement(); }
+    const XMLElement* RootElement() const    { return FirstChildElement(); }
+
+    /** Print the Document. If the Printer is not provided, it will
+        print to stdout. If you provide Printer, this can print to a file:
+        @verbatim
+        XMLPrinter printer( fp );
+        doc.Print( &printer );
+        @endverbatim
+
+        Or you can use a printer to print to memory:
+        @verbatim
+        XMLPrinter printer;
+        doc->Print( &printer );
+        // printer.CStr() has a const char* to the XML
+        @endverbatim
+    */
+    void Print( XMLPrinter* streamer=0 );
+    virtual bool Accept( XMLVisitor* visitor ) const;
+
+    /**
+        Create a new Element associated with
+        this Document. The memory for the Element
+        is managed by the Document.
+    */
+    XMLElement* NewElement( const char* name );
+    /**
+        Create a new Comment associated with
+        this Document. The memory for the Comment
+        is managed by the Document.
+    */
+    XMLComment* NewComment( const char* comment );
+    /**
+        Create a new Text associated with
+        this Document. The memory for the Text
+        is managed by the Document.
+    */
+    XMLText* NewText( const char* text );
+    /**
+        Create a new Declaration associated with
+        this Document. The memory for the object
+        is managed by the Document.
+
+        If the 'text' param is null, the standard
+        declaration is used.:
+        @verbatim
+            <?xml version="1.0" encoding="UTF-8"?>
+        @endverbatim
+    */
+    XMLDeclaration* NewDeclaration( const char* text=0 );
+    /**
+        Create a new Unknown associated with
+        this Document. The memory for the object
+        is managed by the Document.
+    */
+    XMLUnknown* NewUnknown( const char* text );
+
+    /**
+        Delete a node associated with this document.
+        It will be unlinked from the DOM.
+    */
+    void DeleteNode( XMLNode* node )    { node->parent->DeleteChild( node ); }
+
+    void SetError( int error, const char* str1, const char* str2 );
+
+    /// Return true if there was an error parsing the document.
+    bool Error() const { return errorID != XML_NO_ERROR; }
+    /// Return the errorID.
+    int  ErrorID() const { return errorID; }
+    /// Return a possibly helpful diagnostic location or string.
+    const char* GetErrorStr1() const { return errorStr1; }
+    /// Return a possibly helpful secondary diagnostic location or string.
+    const char* GetErrorStr2() const { return errorStr2; }
+    /// If there is an error, print it to stdout.
+    void PrintError() const;
+
+    // internal
+    char* Identify( char* p, XMLNode** node );
+
+    virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const    { return 0; }
+    virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const    { return false; }
+
+private:
+    XMLDocument( const XMLDocument& );    // not supported
+    void operator=( const XMLDocument& );    // not supported
+    void InitDocument();
+
+    bool writeBOM;
+    bool processEntities;
+    int errorID;
+    const char* errorStr1;
+    const char* errorStr2;
+    char* charBuffer;
+
+    MemPoolT< sizeof(XMLElement) >    elementPool;
+    MemPoolT< sizeof(XMLAttribute) > attributePool;
+    MemPoolT< sizeof(XMLText) >        textPool;
+    MemPoolT< sizeof(XMLComment) >    commentPool;
+};
+
+
+/**
+    A XMLHandle is a class that wraps a node pointer with null checks; this is
+    an incredibly useful thing. Note that XMLHandle is not part of the TinyXML
+    DOM structure. It is a separate utility class.
+
+    Take an example:
+    @verbatim
+    <Document>
+        <Element attributeA = "valueA">
+            <Child attributeB = "value1" />
+            <Child attributeB = "value2" />
+        </Element>
+    </Document>
+    @endverbatim
+
+    Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
+    easy to write a *lot* of code that looks like:
+
+    @verbatim
+    XMLElement* root = document.FirstChildElement( "Document" );
+    if ( root )
+    {
+        XMLElement* element = root->FirstChildElement( "Element" );
+        if ( element )
+        {
+            XMLElement* child = element->FirstChildElement( "Child" );
+            if ( child )
+            {
+                XMLElement* child2 = child->NextSiblingElement( "Child" );
+                if ( child2 )
+                {
+                    // Finally do something useful.
+    @endverbatim
+
+    And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
+    of such code. A XMLHandle checks for null pointers so it is perfectly safe
+    and correct to use:
+
+    @verbatim
+    XMLHandle docHandle( &document );
+    XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement();
+    if ( child2 )
+    {
+        // do something useful
+    @endverbatim
+
+    Which is MUCH more concise and useful.
+
+    It is also safe to copy handles - internally they are nothing more than node pointers.
+    @verbatim
+    XMLHandle handleCopy = handle;
+    @endverbatim
+
+    See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
+*/
+class XMLHandle
+{
+public:
+    /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+    XMLHandle( XMLNode* _node )                                                { node = _node; }
+    /// Create a handle from a node.
+    XMLHandle( XMLNode& _node )                                                { node = &_node; }
+    /// Copy constructor
+    XMLHandle( const XMLHandle& ref )                                        { node = ref.node; }
+    /// Assignment
+    XMLHandle& operator=( const XMLHandle& ref )                            { node = ref.node; return *this; }
+
+    /// Get the first child of this handle.
+    XMLHandle FirstChild()                                                     { return XMLHandle( node ? node->FirstChild() : 0 ); }
+    /// Get the first child element of this handle.
+    XMLHandle FirstChildElement( const char* value=0 )                        { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); }
+    /// Get the last child of this handle.
+    XMLHandle LastChild()                                                    { return XMLHandle( node ? node->LastChild() : 0 ); }
+    /// Get the last child element of this handle.
+    XMLHandle LastChildElement( const char* _value=0 )                        { return XMLHandle( node ? node->LastChildElement( _value ) : 0 ); }
+    /// Get the previous sibling of this handle.
+    XMLHandle PreviousSibling()                                                { return XMLHandle( node ? node->PreviousSibling() : 0 ); }
+    /// Get the previous sibling element of this handle.
+    XMLHandle PreviousSiblingElement( const char* _value=0 )                { return XMLHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); }
+    /// Get the next sibling of this handle.
+    XMLHandle NextSibling()                                                    { return XMLHandle( node ? node->NextSibling() : 0 ); }
+    /// Get the next sibling element of this handle.
+    XMLHandle NextSiblingElement( const char* _value=0 )                    { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); }
+
+    /// Safe cast to XMLNode. This can return null.
+    XMLNode* ToNode()                            { return node; }
+    /// Safe cast to XMLElement. This can return null.
+    XMLElement* ToElement()                     { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+    /// Safe cast to XMLText. This can return null.
+    XMLText* ToText()                             { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+    /// Safe cast to XMLUnknown. This can return null.
+    XMLUnknown* ToUnknown()                     { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+    /// Safe cast to XMLDeclaration. This can return null.
+    XMLDeclaration* ToDeclaration()             { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); }
+
+private:
+    XMLNode* node;
+};
+
+
+/**
+    A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
+    same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
+*/
+class XMLConstHandle
+{
+public:
+    XMLConstHandle( const XMLNode* _node )                                            { node = _node; }
+    XMLConstHandle( const XMLNode& _node )                                            { node = &_node; }
+    XMLConstHandle( const XMLConstHandle& ref )                                        { node = ref.node; }
+
+    XMLConstHandle& operator=( const XMLConstHandle& ref )                            { node = ref.node; return *this; }
+
+    const XMLConstHandle FirstChild() const                                            { return XMLConstHandle( node ? node->FirstChild() : 0 ); }
+    const XMLConstHandle FirstChildElement( const char* value=0 ) const                { return XMLConstHandle( node ? node->FirstChildElement( value ) : 0 ); }
+    const XMLConstHandle LastChild()    const                                        { return XMLConstHandle( node ? node->LastChild() : 0 ); }
+    const XMLConstHandle LastChildElement( const char* _value=0 ) const                { return XMLConstHandle( node ? node->LastChildElement( _value ) : 0 ); }
+    const XMLConstHandle PreviousSibling() const                                    { return XMLConstHandle( node ? node->PreviousSibling() : 0 ); }
+    const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const        { return XMLConstHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); }
+    const XMLConstHandle NextSibling() const                                        { return XMLConstHandle( node ? node->NextSibling() : 0 ); }
+    const XMLConstHandle NextSiblingElement( const char* _value=0 ) const            { return XMLConstHandle( node ? node->NextSiblingElement( _value ) : 0 ); }
+
+
+    const XMLNode* ToNode() const                { return node; }
+    const XMLElement* ToElement() const            { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+    const XMLText* ToText() const                { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+    const XMLUnknown* ToUnknown() const            { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+    const XMLDeclaration* ToDeclaration() const    { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); }
+
+private:
+    const XMLNode* node;
+};
+
+
+/**
+    Printing functionality. The XMLPrinter gives you more
+    options than the XMLDocument::Print() method.
+
+    It can:
+    -# Print to memory.
+    -# Print to a file you provide.
+    -# Print XML without a XMLDocument.
+
+    Print to Memory
+
+    @verbatim
+    XMLPrinter printer;
+    doc->Print( &printer );
+    SomeFunction( printer.CStr() );
+    @endverbatim
+
+    Print to a File
+
+    You provide the file pointer.
+    @verbatim
+    XMLPrinter printer( fp );
+    doc.Print( &printer );
+    @endverbatim
+
+    Print without a XMLDocument
+
+    When loading, an XML parser is very useful. However, sometimes
+    when saving, it just gets in the way. The code is often set up
+    for streaming, and constructing the DOM is just overhead.
+
+    The Printer supports the streaming case. The following code
+    prints out a trivially simple XML file without ever creating
+    an XML document.
+
+    @verbatim
+    XMLPrinter printer( fp );
+    printer.OpenElement( "foo" );
+    printer.PushAttribute( "foo", "bar" );
+    printer.CloseElement();
+    @endverbatim
+*/
+class XMLPrinter : public XMLVisitor
+{
+public:
+    /** Construct the printer. If the FILE* is specified,
+        this will print to the FILE. Else it will print
+        to memory, and the result is available in CStr().
+        If 'compact' is set to true, then output is created
+        with only required whitespace and newlines.
+    */
+    XMLPrinter( FILE* file=0, bool compact = false );
+    ~XMLPrinter()    {}
+
+    /** If streaming, write the BOM and declaration. */
+    void PushHeader( bool writeBOM, bool writeDeclaration );
+    /** If streaming, start writing an element.
+        The element must be closed with CloseElement()
+    */
+    void OpenElement( const char* name );
+    /// If streaming, add an attribute to an open element.
+    void PushAttribute( const char* name, const char* value );
+    void PushAttribute( const char* name, int value );
+    void PushAttribute( const char* name, unsigned value );
+    void PushAttribute( const char* name, bool value );
+    void PushAttribute( const char* name, double value );
+    /// If streaming, close the Element.
+    void CloseElement();
+
+    /// Add a text node.
+    void PushText( const char* text, bool cdata=false );
+    /// Add a text node from an integer.
+    void PushText( int value );
+    /// Add a text node from an unsigned.
+    void PushText( unsigned value );
+    /// Add a text node from a bool.
+    void PushText( bool value );
+    /// Add a text node from a float.
+    void PushText( float value );
+    /// Add a text node from a double.
+    void PushText( double value );
+
+    /// Add a comment
+    void PushComment( const char* comment );
+
+    void PushDeclaration( const char* value );
+    void PushUnknown( const char* value );
+
+    virtual bool VisitEnter( const XMLDocument& /*doc*/ );
+    virtual bool VisitExit( const XMLDocument& /*doc*/ )            { return true; }
+
+    virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
+    virtual bool VisitExit( const XMLElement& element );
+
+    virtual bool Visit( const XMLText& text );
+    virtual bool Visit( const XMLComment& comment );
+    virtual bool Visit( const XMLDeclaration& declaration );
+    virtual bool Visit( const XMLUnknown& unknown );
+
+    /**
+        If in print to memory mode, return a pointer to
+        the XML file in memory.
+    */
+    const char* CStr() const { return buffer.Mem(); }
+    /**
+           If in print to memory mode, return the size
+        of the XML file in memory. (Note the size returned
+        includes the terminating null.)
+      */
+      int CStrSize() const { return buffer.Size(); }
+
+private:
+    void SealElement();
+    void PrintSpace( int depth );
+    void PrintString( const char*, bool restrictedEntitySet );    // prints out, after detecting entities.
+    void Print( const char* format, ... );
+
+    bool elementJustOpened;
+    bool firstElement;
+    FILE* fp;
+    int depth;
+    int textDepth;
+    bool processEntities;
+    bool compactMode;
+
+    enum {
+        ENTITY_RANGE = 64,
+        BUF_SIZE = 200
+    };
+    bool entityFlag[ENTITY_RANGE];
+    bool restrictedEntityFlag[ENTITY_RANGE];
+
+    DynArray< const char*, 10 > stack;
+    DynArray< char, 20 > buffer;
+#ifdef _MSC_VER
+    DynArray< char, 20 > accumulator;
+#endif
+};
+
+
+}    // tinyxml2
+
+
+#endif // TINYXML2_INCLUDED
