diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 00000000..2d02d396
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,56 @@
+version: '{build}'
+
+environment:
+  WINFLEXBISON_ARCHIVE: win_flex_bison-2.5.14.zip
+  matrix:
+    - CMAKE_GENERATOR: Visual Studio 14 2015 Win64
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+
+matrix:
+  fast_finish: true
+
+install:
+  - appveyor DownloadFile "https://downloads.sourceforge.net/project/winflexbison/%WINFLEXBISON_ARCHIVE%"
+  - 7z x -y -owinflexbison\ "%WINFLEXBISON_ARCHIVE%" > nul
+  - set Path=%CD%\winflexbison;%Path%
+
+before_build:
+  - cmd: mkdir build
+  - cmd: cd build
+  - cmd: cmake -DCMAKE_CXX_FLAGS_RELEASE="/Od -DNDEBUG" -G"%CMAKE_GENERATOR%" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="install" -DRETDEC_TESTS=ON -DRETDEC_DEV_TOOLS=ON ..
+
+build_script:
+  - cmd: cmake --build . --config Release -- /m
+  # Get wget, etc. needed for install step. If we do this earlier, build step fails.
+  # Otherwise, we could use `cmake --build . --config Release --target install -- -m` and save a few seconds.
+  - set Path=C:\msys64\usr\bin;C:\msys64\mingw64\bin;%Path%
+  - cmd: cmake --build . --config Release --target install
+
+test_script:
+  # Test that install is movable and that it does not need build directory.
+  - cmd: mv install ../retdec-install
+  - cmd: cd ..
+  # Run unit tests.
+  - cmd: C:\msys64\usr\bin\bash.exe retdec-install\bin\retdec-tests-runner.sh
+  # Run decompilation script.
+  - cmd: C:\msys64\usr\bin\bash.exe retdec-install\bin\retdec-decompiler.sh --help
+  # Run simple decompilation.
+  - cmd: C:\msys64\usr\bin\echo.exe -e "#include <stdio.h>\n#include <stdlib.h>\nint main()\n{\n  printf(\"hello world\\\n\");\n  return 0;\n}\n" > hello-orig.c
+  - cmd: cat hello-orig.c
+    # Make sure 32-bit gcc will be used.
+  - set Path=C:\MinGW\bin;%Path%
+  - cmd: gcc.exe -o hello.exe hello-orig.c
+    # Prefer msys64 after we used 32-bit compiler.
+  - set Path=C:\msys64\usr\bin;C:\msys64\mingw64\bin;%Path%
+  - cmd: hello.exe
+  - cmd: C:\msys64\usr\bin\bash.exe retdec-install\bin\retdec-decompiler.sh hello.exe
+  - cmd: cat hello.c
+  - cmd: grep "int main(int argc, char \*\* argv)" hello.c
+
+notifications:
+  - provider: Email
+    to:
+      - '{{commitAuthorEmail}}'
+    on_build_success: false
+    on_build_failure: true
+    on_build_status_changed: true
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..5ce865bb
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,107 @@
+language: cpp
+
+cache: ccache
+
+matrix:
+  fast_finish: true
+  include:
+    - os: linux
+      dist: trusty
+      compiler: gcc-4.9
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - build-essential
+            - gcc-4.8-multilib
+            - gcc-4.9
+            - g++-4.9
+            - cmake
+            - perl
+            - python3
+            - flex
+            - bison
+            - autoconf
+            - automake
+            - libtool
+            - pkg-config
+            - m4
+            - coreutils
+            - zlib1g-dev
+            - libtinfo-dev
+            - wget
+            - bc
+            - upx
+            - openssl
+      env:
+        - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9 && NPROC=$(nproc)"
+        # We need this so that ccache does not cause compilation errors.
+        # e.g. retdec/tests/utils/string_tests.cpp:276:2: error: stray '\' in program
+        - CCACHE_CPP2=true
+
+    - os: osx
+      osx_image: xcode8.3
+      env:
+        - MATRIX_EVAL="NPROC=$(sysctl -n hw.physicalcpu)"
+        - CCACHE_CPP2=true
+
+install:
+  # We need to install newer versions of Flex and Bison on MacOS X.
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install flex bison; fi
+  # ccache is not installed on OS X.
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install ccache; fi
+  # gnu-getopt
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install gnu-getopt; fi
+  # bash 4
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install bash; fi
+
+before_script:
+  - eval "${MATRIX_EVAL}"
+  # We need to use newer versions of Flex and Bison on MacOS X (the ones from Homebrew).
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export CMAKE_INCLUDE_PATH="/usr/local/opt/flex/include"; fi
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export CMAKE_LIBRARY_PATH="/usr/local/opt/flex/lib;/usr/local/opt/bison/lib"; fi
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export PATH="/usr/local/opt/flex/bin:/usr/local/opt/bison/bin:$PATH"; fi
+  # Coreutils.
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export PATH="$(brew --prefix coreutils)/libexec/gnubin:$PATH"; fi
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then ln -s /usr/local/bin/greadlink /usr/local/bin/readlink; fi
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export PATH="/usr/local/opt/gnu-getopt/bin:$PATH"; fi
+  # We need to add ccache before everything else in PATH.
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi
+
+script:
+  - mkdir build && cd build
+  # We use "-O0" to speed-up build.
+  # "-O0" causes segfaults in LLVM if we do not use "-DNDEBUG" as well.
+  - cmake -DCMAKE_CXX_FLAGS_RELEASE="-O0 -DNDEBUG" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DRETDEC_TESTS=ON -DRETDEC_DEV_TOOLS=ON ..
+  - time make install -j $NPROC
+  # Test that install is movable and that it does not need build directory.
+  - mv install ../retdec-install
+  - cd ..
+  - rm -rf build
+  # Run unit tests.
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then /usr/local/bin/bash retdec-install/bin/retdec-tests-runner.sh; fi
+  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then ./retdec-install/bin/retdec-tests-runner.sh; fi
+  # Run decompilation script.
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then /usr/local/bin/bash retdec-install/bin/retdec-decompiler.sh --help; fi
+  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then ./retdec-install/bin/retdec-decompiler.sh --help; fi
+  # Run simple decompilation.
+  - echo -e '#include <stdio.h>\n#include <stdlib.h>\nint main()\n{\n  printf("hello world\\n");\n  return 0;\n}\n' > hello-orig.c
+  - cat hello-orig.c
+  - gcc -m32 -o hello hello-orig.c
+  - ./hello
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then /usr/local/bin/bash retdec-install/bin/retdec-decompiler.sh hello; fi
+  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then ./retdec-install/bin/retdec-decompiler.sh hello; fi
+  - cat hello.c
+  - grep "int main(int argc, char \*\* argv)" hello.c
+
+branches:
+  only:
+    # Pushes and PRs to the master branch.
+    - master
+    # Version tags.
+    - /^v?\d+\.\d+.*$/
+
+notifications:
+  email:
+    on_success: never
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d1f2773..1735813e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,10 +2,12 @@
 
 # dev
 
+* Enhancement: Speeded up build by skipping compilation of unnecessary dependencies (e.g. unused LLVM libraries, tools, and examples).
+* Enhancement: OpenSSL is now automatically built only if it is not found in your system.
 * Enhancement: Added support for a system-wide installation ([#94](https://github.com/avast-tl/retdec/issues/94)).
 * Enhancement: Prefixed all the installed binaries and scripts with `retdec-` ([#70](https://github.com/avast-tl/retdec/issues/70)). Also, some tools were renamed to make their names more uniform.
 * Enhancement: Got rid of all git submodules ([#92](https://github.com/avast-tl/retdec/issues/92), [#93](https://github.com/avast-tl/retdec/issues/93)). Moved sources of all RetDec-related repositories to this main repository. Third-party dependencies are downloaded and built via CMake's external projects. This allows us to have e.g. only a single copy of LLVM ([#14](https://github.com/avast-tl/retdec/issues/14)) and not require a recursive clone ([#48](https://github.com/avast-tl/retdec/issues/48), [#68](https://github.com/avast-tl/retdec/issues/68), [#72](https://github.com/avast-tl/retdec/issues/72)).
-* Enhancement: Set a proper `rpath` during installation on Linux and macOS ([#77](https://github.com/avast-tl/retdec/issues/77)). This allows us to move the installation directory after the installation into another location.
+* Enhancement: Set a proper `rpath` during installation on Linux and macOS ([#77](https://github.com/avast-tl/retdec/issues/77), [#100](https://github.com/avast-tl/retdec/issues/100)). This allows us to move the installation directory after the installation into another location.
 * Enhancement: Added community support for building and running RetDec inside Docker ([#60](https://github.com/avast-tl/retdec/pull/60)).
 * Enhancement: Decrease the default timeout when downloading the support package during installation ([#6](https://github.com/avast-tl/retdec/pull/6)).
 * Enhancement: Any shell can be used to install the decompiler, not just Bash.
@@ -22,6 +24,7 @@
 * Fix: When installing the decompiler, do not remove the entire `share` directory ([#12](https://github.com/avast-tl/retdec/issues/12)).
 * Fix: Improve OS type detection when installing the decompiler.
 * Fix: Remove useless OS type detection when running decompilations ([#10](https://github.com/avast-tl/retdec/issues/10)).
+* Fix: Filesystem path in utils now returns correct information when it is appended with another path.
 
 # v3.0 (2017-12-13)
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c7cdf61..5ceb30ac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -38,7 +38,34 @@ endif()
 set(EP_PREFIX "${PROJECT_BINARY_DIR}/external")
 set_directory_properties(PROPERTIES EP_PREFIX "${EP_PREFIX}")
 
-set(DEPS_TESTS ${RETDEC_TESTS})
+# Compilation warnings.
+if(MSVC)
+	# For the moment, suppress all warnings when building with MSVC on Windows
+	# because there are too many warnings that clutter the build output (#106).
+	# We should investigate the warnings, fix them, and then enable their
+	# emission (e.g. by replacing /W0 with /W3 in the code below).
+	if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
+		string(REGEX REPLACE "/W[0-4]" "/W0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+	else()
+		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0")
+	endif()
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
+		CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR
+		CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+	# Enable standard warnings.
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
+
+	# Enable additional warnings that are not included in -Wall and -Wextra.
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wswitch-default")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuninitialized")
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast")
+
+	# Disable warnings that produce more headaches than use.
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
+endif()
+
 include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/install-external.cmake)
 
 add_subdirectory(deps)
diff --git a/README.md b/README.md
index 9f50b51e..4afd7b85 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
 # RetDec
 
+[![Travis CI build status](https://travis-ci.org/avast-tl/retdec.svg?branch=master)](https://travis-ci.org/avast-tl/retdec)
+[![AppVeyor build status](https://ci.appveyor.com/api/projects/status/github/avast-tl/retdec?branch=master&svg=true)](https://ci.appveyor.com/project/avast-tl/retdec)
+
 [RetDec](https://retdec.com/) is a retargetable machine-code decompiler based on [LLVM](https://llvm.org/).
 
 The decompiler is not limited to any particular target architecture, operating system, or executable file format:
diff --git a/deps/capstone/CMakeLists.txt b/deps/capstone/CMakeLists.txt
index c193d83d..3b53ebb8 100644
--- a/deps/capstone/CMakeLists.txt
+++ b/deps/capstone/CMakeLists.txt
@@ -1,13 +1,42 @@
 include(ExternalProject)
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 ExternalProject_Add(capstone-project
 	URL https://github.com/avast-tl/capstone/archive/27c713fe4f6eaf9721785932d850b6291a6073fe.zip
 	URL_HASH SHA256=4d8d0461d7d5737893253698cd0b6d0d64545c1a74b166e8b1d823156a3109cb
+	DOWNLOAD_NAME capstone.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
+		-DCAPSTONE_BUILD_STATIC=ON
 		-DCAPSTONE_BUILD_SHARED=OFF
 		-DCAPSTONE_BUILD_STATIC_RUNTIME=OFF
+		-DCAPSTONE_BUILD_TESTS=OFF
+		-DCAPSTONE_X86_ATT_DISABLE=OFF
+		# Enabled architectures.
+		-DCAPSTONE_ARM_SUPPORT=ON
+		-DCAPSTONE_MIPS_SUPPORT=ON
+		-DCAPSTONE_PPC_SUPPORT=ON
+		-DCAPSTONE_X86_SUPPORT=ON
+		# Disabled architectures.
+		-DCAPSTONE_ARM64_SUPPORT=OFF
+		-DCAPSTONE_M68K_SUPPORT=OFF
+		-DCAPSTONE_SPARC_SUPPORT=OFF
+		-DCAPSTONE_SYSZ_SUPPORT=OFF
+		-DCAPSTONE_XCORE_SUPPORT=OFF
+		-DCAPSTONE_TMS320C64X_SUPPORT=OFF
+		-DCAPSTONE_M680X_SUPPORT=OFF
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
 	# Disable the update step.
 	UPDATE_COMMAND ""
 	# Disable the install step.
diff --git a/deps/elfio/CMakeLists.txt b/deps/elfio/CMakeLists.txt
index 1648d119..0b28863d 100644
--- a/deps/elfio/CMakeLists.txt
+++ b/deps/elfio/CMakeLists.txt
@@ -1,11 +1,26 @@
 include(ExternalProject)
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 ExternalProject_Add(elfio-project
 	URL https://github.com/avast-tl/elfio/archive/1677a88d902d0fa6a5a7a31dc4da45748bba0bde.zip
 	URL_HASH SHA256=a446b2751b177bde6c5bff5a3716a978918daba6f4953aeef3850036cb43fde7
+	DOWNLOAD_NAME elfio.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
+	# Disable the configure step - header only.
+	CONFIGURE_COMMAND ""
 	# Disable the build step.
 	BUILD_COMMAND ""
 	# Disable the update step.
diff --git a/deps/googletest/CMakeLists.txt b/deps/googletest/CMakeLists.txt
index 7f931939..597b3c6e 100644
--- a/deps/googletest/CMakeLists.txt
+++ b/deps/googletest/CMakeLists.txt
@@ -10,8 +10,9 @@ if(CMAKE_CXX_COMPILER)
 endif()
 
 ExternalProject_Add(googletest
-	URL https://github.com/google/googletest/archive/5490beb0602eab560fa3969a4410e11d94bf12af.zip
-	URL_HASH SHA256=fb94ea2c653f239fb57e423afef372ebb5e019418af58f8bb2ce946679a6187b
+	URL https://github.com/google/googletest/archive/83fa0cb17dad47a1d905526dcdddb5b96ed189d2.zip
+	URL_HASH SHA256=3b7cf6bfd1fdec3204933b4c0419c010e89b2409dcd8cbc1ac6a78aab058e2b0
+	DOWNLOAD_NAME googletest.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but is useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
@@ -44,28 +45,32 @@ ExternalProject_Get_Property(googletest binary_dir)
 if(MSVC)
 	set(DEBUG_DIR "Debug/")
 	set(RELEASE_DIR "Release/")
+	set(DEBUG_LIB_SUFFIX "d")
 endif()
 
 add_library(gtest INTERFACE)
-target_link_libraries(gtest INTERFACE debug ${binary_dir}/googlemock/gtest/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(gtest INTERFACE debug ${binary_dir}/googlemock/gtest/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gtest${DEBUG_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries(gtest INTERFACE optimized ${binary_dir}/googlemock/gtest/${RELEASE_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
 target_include_directories(gtest SYSTEM INTERFACE ${GTEST_INCLUDE_DIR})
 add_dependencies(gtest googletest)
 
 add_library(gtest_main INTERFACE)
-target_link_libraries(gtest_main INTERFACE debug ${binary_dir}/googlemock/gtest/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(gtest_main INTERFACE debug ${binary_dir}/googlemock/gtest/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${DEBUG_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries(gtest_main INTERFACE optimized ${binary_dir}/googlemock/gtest/${RELEASE_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(gtest_main INTERFACE gtest)
 target_include_directories(gtest_main SYSTEM INTERFACE ${GTEST_INCLUDE_DIR})
 add_dependencies(gtest_main googletest)
 
 add_library(gmock INTERFACE)
-target_link_libraries(gmock INTERFACE debug ${binary_dir}/googlemock/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(gmock INTERFACE debug ${binary_dir}/googlemock/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gmock${DEBUG_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries(gmock INTERFACE optimized ${binary_dir}/googlemock/${RELEASE_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(gmock INTERFACE gtest)
 target_include_directories(gmock SYSTEM INTERFACE ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR})
 add_dependencies(gmock googletest)
 
 add_library(gmock_main INTERFACE)
-target_link_libraries(gmock_main INTERFACE debug ${binary_dir}/googlemock/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(gmock_main INTERFACE debug ${binary_dir}/googlemock/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gmock_main${DEBUG_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries(gmock_main INTERFACE optimized ${binary_dir}/googlemock/${RELEASE_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(gmock_main INTERFACE gmock)
 target_include_directories(gmock_main SYSTEM INTERFACE ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR})
 add_dependencies(gmock_main googletest)
diff --git a/deps/jsoncpp/CMakeLists.txt b/deps/jsoncpp/CMakeLists.txt
index 656074cd..274eddac 100644
--- a/deps/jsoncpp/CMakeLists.txt
+++ b/deps/jsoncpp/CMakeLists.txt
@@ -10,6 +10,7 @@ endif()
 ExternalProject_Add(jsoncpp-project
 	URL https://github.com/open-source-parsers/jsoncpp/archive/1.8.4.zip
 	URL_HASH SHA256=2979436dbd4c48a3284dca9fa8f212298425ba3920ed6bacdda8905a94b111a8
+	DOWNLOAD_NAME jsoncpp.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
@@ -18,6 +19,11 @@ ExternalProject_Add(jsoncpp-project
 		# compiler, which may result in link errors.
 		"${CMAKE_C_COMPILER_OPTION}"
 		"${CMAKE_CXX_COMPILER_OPTION}"
+		# Disable unused options.
+		-DJSONCPP_WITH_TESTS=OFF
+		-DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF
+		-DJSONCPP_WITH_PKGCONFIG_SUPPORT=OFF
+		-DBUILD_SHARED_LIBS=OFF
 	# Disable the update step.
 	UPDATE_COMMAND ""
 	# Disable the install step.
diff --git a/deps/keystone/CMakeLists.txt b/deps/keystone/CMakeLists.txt
index d034c7a6..d248004e 100644
--- a/deps/keystone/CMakeLists.txt
+++ b/deps/keystone/CMakeLists.txt
@@ -1,5 +1,12 @@
 include(ExternalProject)
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 # Keystone requires python3, so we first check whether python3 is installed as
 # "python3", and if not, we suppose that `python` runs python3.
 # Python is used to generate LLVMBuild.cmake file. Python2 generates this file
@@ -12,12 +19,18 @@ endif()
 ExternalProject_Add(keystone-project
 	URL https://github.com/avast-tl/keystone/archive/4722974f58dbe878c805ce2b7c0a41cf6153903c.zip
 	URL_HASH SHA256=145c8bb836d2f06f845b5015b3eab350ae59d35a54052f00f5d26445172415fd
+	DOWNLOAD_NAME keystone.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
 		# Force python version set in this cmake file.
 		-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
 		-DKEYSTONE_BUILD_STATIC_RUNTIME=OFF
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
 	# Disable the update step.
 	UPDATE_COMMAND ""
 	# Disable the install step.
diff --git a/deps/libdwarf/CMakeLists.txt b/deps/libdwarf/CMakeLists.txt
index ec9e6164..397c8daf 100644
--- a/deps/libdwarf/CMakeLists.txt
+++ b/deps/libdwarf/CMakeLists.txt
@@ -1,15 +1,28 @@
 include(ExternalProject)
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 set(LIBDWARF_INSTALL_DIR "${PROJECT_BINARY_DIR}/external/src/libdwarf-project-install")
 
 ExternalProject_Add(libdwarf-project
-	URL https://github.com/avast-tl/libdwarf/archive/bb920ecb8b6172359b4d57955a2670194d1f1f43.zip
-	URL_HASH SHA256=b28a6f9fc854d7e1dce84c892b522b9ae98b2d600f82d9f1cc10e470f926ab98
+	URL https://github.com/avast-tl/libdwarf/archive/85465d5e235cc2d2f90d04016d6aca1a452d0e73.zip
+	URL_HASH SHA256=2864aa7b46529778476190e90359669eb35799ad273233c4df2203bec7db0738
+	DOWNLOAD_NAME libdwarf.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
 		-DCMAKE_INSTALL_PREFIX=${LIBDWARF_INSTALL_DIR}
 		-DLIBDWARF_INSTALL_TO_UNITTESTS=${RETDEC_TESTS}
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
 	# Disable the update step.
 	UPDATE_COMMAND ""
 	LOG_DOWNLOAD ON
diff --git a/deps/llvm/CMakeLists.txt b/deps/llvm/CMakeLists.txt
index 4129f87d..bf8ff7fe 100644
--- a/deps/llvm/CMakeLists.txt
+++ b/deps/llvm/CMakeLists.txt
@@ -3,6 +3,13 @@ if(UNIX)
 	find_package(ZLIB REQUIRED)
 endif()
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 # Set the default build type to 'Release'
 if (NOT CMAKE_BUILD_TYPE)
 	set(default_build_type "Release")
@@ -28,8 +35,9 @@ if(NOT PYTHON_EXECUTABLE)
 endif()
 
 ExternalProject_Add(llvm-project
-	URL https://github.com/avast-tl/llvm/archive/e7431aa1980227e15caf296bd1a8da85aa5706f4.zip
-	URL_HASH SHA256=d30752a7cd23597cf54513b6ea69fa8c1311c631bd7bbfc816737249664443e9
+	URL https://github.com/avast-tl/llvm/archive/257248365d034351e164aae04060f0d8f4c5b1f1.zip
+	URL_HASH SHA256=0088e715fd92d9670398514791563f1efc727d5a81b5cac8830c7e746ab26c06
+	DOWNLOAD_NAME llvm.zip
 	CMAKE_ARGS
 		# Force a release build (we don't need to debug LLVM).
 		# This has no effect on Windows with MSVC, but is useful on Linux.
@@ -66,6 +74,17 @@ ExternalProject_Add(llvm-project
 		#                     need to also link the tinfo library.
 		-DLLVM_ENABLE_TERMINFO=YES
 
+		# Disable build of unnecessary LLVM parts.
+		-DLLVM_BUILD_TOOLS=OFF
+		-DLLVM_BUILD_UTILS=OFF
+		-DLLVM_BUILD_RUNTIME=OFF
+
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
+
 	# Disable the installation right after build (we want to install the
 	# needed libraries and tools manually).
 	INSTALL_COMMAND ""
@@ -97,47 +116,24 @@ add_library(llvm INTERFACE)
 add_dependencies(llvm llvm-project)
 
 set(LLVM_LIB_LIST
-	LLVMInterpreter
-	LLVMMCJIT
-	LLVMRuntimeDyld
-	LLVMOrcJIT
-	LLVMExecutionEngine
-	LLVMRuntimeDyld
-	LLVMX86CodeGen
-	LLVMX86AsmParser
-	LLVMX86Disassembler
 	LLVMBitWriter
 	LLVMIRReader
-	LLVMInstrumentation
 	LLVMObject
+	LLVMInstCombine
 	LLVMSupport
 	LLVMipo
-	LLVMAsmPrinter
-	LLVMSelectionDAG
-	LLVMX86Desc
 	LLVMAsmParser
 	LLVMBitReader
-	LLVMVectorize
 	LLVMMCParser
 	LLVMCodeGen
-	LLVMX86AsmPrinter
-	LLVMX86Info
-	LLVMObjCARCOpts
 	LLVMScalarOpts
-	LLVMX86Utils
 	LLVMTransformUtils
 	LLVMAnalysis
 	LLVMTarget
 	LLVMCore
 	LLVMMC
 	LLVMObject
-	LLVMMCDisassembler
-	LLVMProfileData
-	LLVMDebugInfoCodeView
 	LLVMPasses
-	LLVMLinker
-	LLVMInstCombine
-	LLVMSupport
 )
 
 if(MSVC)
diff --git a/deps/openssl/CMakeLists.txt b/deps/openssl/CMakeLists.txt
index 60415674..2ac11457 100644
--- a/deps/openssl/CMakeLists.txt
+++ b/deps/openssl/CMakeLists.txt
@@ -1,3 +1,12 @@
+
+find_package(OpenSSL 1.0.1)
+if(OPENSSL_FOUND)
+	add_library(openssl-crypto INTERFACE)
+	target_link_libraries(openssl-crypto INTERFACE OpenSSL::Crypto)
+	return()
+endif()
+message(STATUS "  --> OpenSSL will be built as an external project")
+
 find_package(Perl REQUIRED)
 
 include(ExternalProject)
@@ -82,6 +91,7 @@ set(OPENSSL_INSTALL_DIR    "${OPENSSL_PREFIX}/src/openssl-install")
 set(OPENSSL_VERSION        "1.1.0f")
 set(OPENSSL_URL            "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz")
 set(OPENSSL_ARCHIVE_SHA256 "12f746f3f2493b2f39da7ecf63d7ee19c6ac9ec6a4fcd8c229da8a522cb12765")
+set(OPENSSL_DOWNLOAD_NAME  "openssl.tar.gz")
 
 set(OPENSSL_CONFIGURE_OPTIONS
 	no-shared
@@ -96,6 +106,7 @@ if (NOT TARGET openssl)
 		PREFIX ${OPENSSL_PREFIX}
 		URL ${OPENSSL_URL}
 		URL_HASH SHA256=${OPENSSL_ARCHIVE_SHA256}
+		DOWNLOAD_NAME ${OPENSSL_DOWNLOAD_NAME}
 		CONFIGURE_COMMAND
 			${PERL_EXECUTABLE}
 			${OPENSSL_SRC_DIR}/Configure
@@ -105,7 +116,9 @@ if (NOT TARGET openssl)
 		BUILD_COMMAND
 			${OPENSSL_MAKE}
 		INSTALL_COMMAND
-			${OPENSSL_MAKE} install
+			# Install only the software parts (libraries and includes), not
+			# e.g. documentation and manual pages.
+			${OPENSSL_MAKE} install_sw
 		LOG_DOWNLOAD 1
 		LOG_BUILD 1
 		LOG_CONFIGURE 1
diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt
index 09a57976..39ff2ed4 100644
--- a/deps/pelib/CMakeLists.txt
+++ b/deps/pelib/CMakeLists.txt
@@ -1,11 +1,24 @@
 include(ExternalProject)
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 ExternalProject_Add(pelib-project
 	URL https://github.com/avast-tl/pelib/archive/e93eaa7c150f4608a5d02a67f5edc9e54456fe24.zip
 	URL_HASH SHA256=2ffd7e89451c980a1af6d24d4f6dfbb69a660b06ad5de44c481f6431e21de394
+	DOWNLOAD_NAME pelib.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
 	# Disable the update step.
 	UPDATE_COMMAND ""
 	# Disable the install step.
diff --git a/deps/rapidjson/CMakeLists.txt b/deps/rapidjson/CMakeLists.txt
index c6e6af38..4ae43d04 100644
--- a/deps/rapidjson/CMakeLists.txt
+++ b/deps/rapidjson/CMakeLists.txt
@@ -1,14 +1,27 @@
 include(ExternalProject)
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 ExternalProject_Add(rapidjson-project
 	URL https://github.com/Tencent/rapidjson/archive/v1.1.0.zip
 	URL_HASH SHA256=8e00c38829d6785a2dfb951bb87c6974fa07dfe488aa5b25deec4b8bc0f6a3ab
+	DOWNLOAD_NAME rapidjson.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
 		-DRAPIDJSON_BUILD_DOC=OFF
 		-DRAPIDJSON_BUILD_EXAMPLES=OFF
 		-DRAPIDJSON_BUILD_TESTS=OFF
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
 	# Disable the build step.
 	BUILD_COMMAND ""
 	# Disable the update step.
diff --git a/deps/tinyxml2/CMakeLists.txt b/deps/tinyxml2/CMakeLists.txt
index 425265bb..bf42f81f 100644
--- a/deps/tinyxml2/CMakeLists.txt
+++ b/deps/tinyxml2/CMakeLists.txt
@@ -1,2 +1,53 @@
-add_library(tinyxml2 STATIC tinyxml2.cpp)
-target_include_directories(tinyxml2 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
+include(ExternalProject)
+
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
+ExternalProject_Add(tinyxml2-project
+	URL https://github.com/leethomason/tinyxml2/archive/cc1745b552dd12bb1297a99f82044f83b06729e0.zip
+	URL_HASH SHA256=de255ce39ba1efe20cbffdebd3eea2d08f1269d03440a4fd60e142b0481c3f00
+	DOWNLOAD_NAME tinyxml2.zip
+	CMAKE_ARGS
+		# This does not work on MSVC, but may be useful on Linux.
+		-DCMAKE_BUILD_TYPE=Release
+		# Build only static library.
+		-DBUILD_STATIC_LIBS:BOOL=ON
+		-DBUILD_SHARED_LIBS:BOOL=OFF
+		# Do not build tests.
+		-DBUILD_TESTS:BOOL=OFF
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
+	# Disable the update step.
+	UPDATE_COMMAND ""
+	# Disable the install step.
+	INSTALL_COMMAND ""
+	LOG_DOWNLOAD ON
+	LOG_CONFIGURE ON
+	LOG_BUILD ON
+)
+
+# Set include directories.
+ExternalProject_Get_Property(tinyxml2-project source_dir)
+set(TINYXML2_INCLUDE_DIR ${source_dir})
+
+# Add libraries.
+ExternalProject_Get_Property(tinyxml2-project binary_dir)
+
+if(MSVC)
+	set(DEBUG_DIR "Debug/")
+	set(RELEASE_DIR "Release/")
+	set(DEBUG_LIB_SUFFIX "d")
+endif()
+
+add_library(tinyxml2 INTERFACE)
+target_link_libraries(tinyxml2 INTERFACE debug ${binary_dir}/${DEBUG_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}tinyxml2${DEBUG_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
+target_link_libraries(tinyxml2 INTERFACE optimized ${binary_dir}/${RELEASE_DIR}${CMAKE_STATIC_LIBRARY_PREFIX}tinyxml2${CMAKE_STATIC_LIBRARY_SUFFIX})
+target_include_directories(tinyxml2 SYSTEM INTERFACE ${TINYXML2_INCLUDE_DIR})
+add_dependencies(tinyxml2 tinyxml2-project)
diff --git a/deps/tinyxml2/tinyxml2.cpp b/deps/tinyxml2/tinyxml2.cpp
deleted file mode 100644
index c7116c9e..00000000
--- a/deps/tinyxml2/tinyxml2.cpp
+++ /dev/null
@@ -1,2741 +0,0 @@
-/*
-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 <new>		// yes, this one new style header, is in the Android SDK.
-#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
-#   include <stddef.h>
-#   include <stdarg.h>
-#else
-#   include <cstddef>
-#   include <cstdarg>
-#endif
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
-	// Microsoft Visual Studio, version 2005 and higher. Not WinCE.
-	/*int _snprintf_s(
-	   char *buffer,
-	   size_t sizeOfBuffer,
-	   size_t count,
-	   const char *format [,
-		  argument] ...
-	);*/
-	static 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;
-	}
-
-	static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va )
-	{
-		int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
-		return result;
-	}
-
-	#define TIXML_VSCPRINTF	_vscprintf
-	#define TIXML_SSCANF	sscanf_s
-#elif defined _MSC_VER
-	// Microsoft Visual Studio 2003 and earlier or WinCE
-	#define TIXML_SNPRINTF	_snprintf
-	#define TIXML_VSNPRINTF _vsnprintf
-	#define TIXML_SSCANF	sscanf
-	#if (_MSC_VER < 1400 ) && (!defined WINCE)
-		// Microsoft Visual Studio 2003 and not WinCE.
-		#define TIXML_VSCPRINTF   _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have.
-	#else
-		// Microsoft Visual Studio 2003 and earlier or WinCE.
-		static inline int TIXML_VSCPRINTF( const char* format, va_list va )
-		{
-			int len = 512;
-			for (;;) {
-				len = len*2;
-				char* str = new char[len]();
-				const int required = _vsnprintf(str, len, format, va);
-				delete[] str;
-				if ( required != -1 ) {
-					TIXMLASSERT( required >= 0 );
-					len = required;
-					break;
-				}
-			}
-			TIXMLASSERT( len >= 0 );
-			return len;
-		}
-	#endif
-#else
-	// GCC version 3 and higher
-	//#warning( "Using sn* functions." )
-	#define TIXML_SNPRINTF	snprintf
-	#define TIXML_VSNPRINTF	vsnprintf
-	static inline int TIXML_VSCPRINTF( const char* format, va_list va )
-	{
-		int len = vsnprintf( 0, 0, format, va );
-		TIXMLASSERT( len >= 0 );
-		return len;
-	}
-	#define TIXML_SSCANF   sscanf
-#endif
-
-
-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;
-
-namespace tinyxml2
-{
-
-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::TransferTo( StrPair* other )
-{
-    if ( this == other ) {
-        return;
-    }
-    // This in effect implements the assignment operator by "moving"
-    // ownership (as in auto_ptr).
-
-    TIXMLASSERT( other != 0 );
-    TIXMLASSERT( other->_flags == 0 );
-    TIXMLASSERT( other->_start == 0 );
-    TIXMLASSERT( other->_end == 0 );
-
-    other->Reset();
-
-    other->_flags = _flags;
-    other->_start = _start;
-    other->_end = _end;
-
-    _flags = 0;
-    _start = 0;
-    _end = 0;
-}
-
-void StrPair::Reset()
-{
-    if ( _flags & NEEDS_DELETE ) {
-        delete [] _start;
-    }
-    _flags = 0;
-    _start = 0;
-    _end = 0;
-}
-
-
-void StrPair::SetStr( const char* str, int flags )
-{
-    TIXMLASSERT( str );
-    Reset();
-    size_t len = strlen( str );
-    TIXMLASSERT( _start == 0 );
-    _start = new char[ len+1 ];
-    memcpy( _start, str, len+1 );
-    _end = _start + len;
-    _flags = flags | NEEDS_DELETE;
-}
-
-
-char* StrPair::ParseText( char* p, const char* endTag, int strFlags, int* curLineNumPtr )
-{
-    TIXMLASSERT( p );
-    TIXMLASSERT( endTag && *endTag );
-	TIXMLASSERT(curLineNumPtr);
-
-    char* start = p;
-    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;
-        } else if (*p == '\n') {
-            ++(*curLineNumPtr);
-        }
-        ++p;
-        TIXMLASSERT( p );
-    }
-    return 0;
-}
-
-
-char* StrPair::ParseName( char* p )
-{
-    if ( !p || !(*p) ) {
-        return 0;
-    }
-    if ( !XMLUtil::IsNameStartChar( *p ) ) {
-        return 0;
-    }
-
-    char* const start = p;
-    ++p;
-    while ( *p && XMLUtil::IsNameChar( *p ) ) {
-        ++p;
-    }
-
-    Set( start, p, 0 );
-    return p;
-}
-
-
-void StrPair::CollapseWhitespace()
-{
-    // Adjusting _start would cause undefined behavior on delete[]
-    TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 );
-    // Trim leading space.
-    _start = XMLUtil::SkipWhiteSpace( _start, 0 );
-
-    if ( *_start ) {
-        const char* p = _start;	// the read pointer
-        char* q = _start;	// the write pointer
-
-        while( *p ) {
-            if ( XMLUtil::IsWhiteSpace( *p )) {
-                p = XMLUtil::SkipWhiteSpace( p, 0 );
-                if ( *p == 0 ) {
-                    break;    // don't write to q; this trims the trailing space.
-                }
-                *q = ' ';
-                ++q;
-            }
-            *q = *p;
-            ++q;
-            ++p;
-        }
-        *q = 0;
-    }
-}
-
-
-const char* StrPair::GetStr()
-{
-    TIXMLASSERT( _start );
-    TIXMLASSERT( _end );
-    if ( _flags & NEEDS_FLUSH ) {
-        *_end = 0;
-        _flags ^= NEEDS_FLUSH;
-
-        if ( _flags ) {
-            const 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;
-                    ++q;
-                }
-                else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) {
-                    if ( *(p+1) == CR ) {
-                        p += 2;
-                    }
-                    else {
-                        ++p;
-                    }
-                    *q = LF;
-                    ++q;
-                }
-                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) == '#' ) {
-                        const int buflen = 10;
-                        char buf[buflen] = { 0 };
-                        int len = 0;
-                        char* adjusted = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );
-                        if ( adjusted == 0 ) {
-                            *q = *p;
-                            ++p;
-                            ++q;
-                        }
-                        else {
-                            TIXMLASSERT( 0 <= len && len <= buflen );
-                            TIXMLASSERT( q + len <= adjusted );
-                            p = adjusted;
-                            memcpy( q, buf, len );
-                            q += len;
-                        }
-                    }
-                    else {
-                        bool entityFound = false;
-                        for( int i = 0; i < NUM_ENTITIES; ++i ) {
-                            const Entity& entity = entities[i];
-                            if ( strncmp( p + 1, entity.pattern, entity.length ) == 0
-                                    && *( p + entity.length + 1 ) == ';' ) {
-                                // Found an entity - convert.
-                                *q = entity.value;
-                                ++q;
-                                p += entity.length + 2;
-                                entityFound = true;
-                                break;
-                            }
-                        }
-                        if ( !entityFound ) {
-                            // fixme: treat as error?
-                            ++p;
-                            ++q;
-                        }
-                    }
-                }
-                else {
-                    *q = *p;
-                    ++p;
-                    ++q;
-                }
-            }
-            *q = 0;
-        }
-        // The loop below has plenty going on, and this
-        // is a less useful mode. Break it out.
-        if ( _flags & NEEDS_WHITESPACE_COLLAPSING ) {
-            CollapseWhitespace();
-        }
-        _flags = (_flags & NEEDS_DELETE);
-    }
-    TIXMLASSERT( _start );
-    return _start;
-}
-
-
-
-
-// --------- XMLUtil ----------- //
-
-const char* XMLUtil::writeBoolTrue  = "true";
-const char* XMLUtil::writeBoolFalse = "false";
-
-void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse)
-{
-	static const char* defTrue  = "true";
-	static const char* defFalse = "false";
-
-	writeBoolTrue = (writeTrue) ? writeTrue : defTrue;
-	writeBoolFalse = (writeFalse) ? writeFalse : defFalse;
-}
-
-
-const char* XMLUtil::ReadBOM( const char* p, bool* bom )
-{
-    TIXMLASSERT( p );
-    TIXMLASSERT( 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;
-    }
-    TIXMLASSERT( p );
-    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;    // This code won't convert this correctly anyway.
-        return;
-    }
-
-    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]);
-            break;
-        default:
-            TIXMLASSERT( false );
-    }
-}
-
-
-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;
-        TIXMLASSERT( sizeof( ucs ) >= 4 );
-        ptrdiff_t delta = 0;
-        unsigned mult = 1;
-        static const char SEMICOLON = ';';
-
-        if ( *(p+2) == 'x' ) {
-            // Hexadecimal.
-            const char* q = p+3;
-            if ( !(*q) ) {
-                return 0;
-            }
-
-            q = strchr( q, SEMICOLON );
-
-            if ( !q ) {
-                return 0;
-            }
-            TIXMLASSERT( *q == SEMICOLON );
-
-            delta = q-p;
-            --q;
-
-            while ( *q != 'x' ) {
-                unsigned int digit = 0;
-
-                if ( *q >= '0' && *q <= '9' ) {
-                    digit = *q - '0';
-                }
-                else if ( *q >= 'a' && *q <= 'f' ) {
-                    digit = *q - 'a' + 10;
-                }
-                else if ( *q >= 'A' && *q <= 'F' ) {
-                    digit = *q - 'A' + 10;
-                }
-                else {
-                    return 0;
-                }
-                TIXMLASSERT( digit < 16 );
-                TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
-                const unsigned int digitScaled = mult * digit;
-                TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
-                ucs += digitScaled;
-                TIXMLASSERT( mult <= UINT_MAX / 16 );
-                mult *= 16;
-                --q;
-            }
-        }
-        else {
-            // Decimal.
-            const char* q = p+2;
-            if ( !(*q) ) {
-                return 0;
-            }
-
-            q = strchr( q, SEMICOLON );
-
-            if ( !q ) {
-                return 0;
-            }
-            TIXMLASSERT( *q == SEMICOLON );
-
-            delta = q-p;
-            --q;
-
-            while ( *q != '#' ) {
-                if ( *q >= '0' && *q <= '9' ) {
-                    const unsigned int digit = *q - '0';
-                    TIXMLASSERT( digit < 10 );
-                    TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
-                    const unsigned int digitScaled = mult * digit;
-                    TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
-                    ucs += digitScaled;
-                }
-                else {
-                    return 0;
-                }
-                TIXMLASSERT( mult <= UINT_MAX / 10 );
-                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, "%s", v ? writeBoolTrue : writeBoolFalse);
-}
-
-/*
-	ToStr() of a number is a very tricky topic.
-	https://github.com/leethomason/tinyxml2/issues/106
-*/
-void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
-{
-    TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v );
-}
-
-
-void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
-{
-    TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v );
-}
-
-
-void XMLUtil::ToStr(int64_t v, char* buffer, int bufferSize)
-{
-	// horrible syntax trick to make the compiler happy about %lld
-	TIXML_SNPRINTF(buffer, bufferSize, "%lld", (long long)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;
-}
-
-
-bool XMLUtil::ToInt64(const char* str, int64_t* value)
-{
-	long long v = 0;	// horrible syntax trick to make the compiler happy about %lld
-	if (TIXML_SSCANF(str, "%lld", &v) == 1) {
-		*value = (int64_t)v;
-		return true;
-	}
-	return false;
-}
-
-
-char* XMLDocument::Identify( char* p, XMLNode** node )
-{
-    TIXMLASSERT( node );
-    TIXMLASSERT( p );
-    char* const start = p;
-    int const startLine = _parseCurLineNum;
-    p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum );
-    if( !*p ) {
-        *node = 0;
-        TIXMLASSERT( p );
-        return p;
-    }
-
-    // These strings define the matching patterns:
-    static const char* xmlHeader		= { "<?" };
-    static const char* commentHeader	= { "<!--" };
-    static const char* cdataHeader		= { "<![CDATA[" };
-    static const char* dtdHeader		= { "<!" };
-    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 cdataHeaderLen		= 9;
-    static const int dtdHeaderLen		= 2;
-    static const int elementHeaderLen	= 1;
-
-    TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) );		// use same memory pool
-    TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) );	// use same memory pool
-    XMLNode* returnNode = 0;
-    if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
-        returnNode = CreateUnlinkedNode<XMLDeclaration>( _commentPool );
-        returnNode->_parseLineNum = _parseCurLineNum;
-        p += xmlHeaderLen;
-    }
-    else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) {
-        returnNode = CreateUnlinkedNode<XMLComment>( _commentPool );
-        returnNode->_parseLineNum = _parseCurLineNum;
-        p += commentHeaderLen;
-    }
-    else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) {
-        XMLText* text = CreateUnlinkedNode<XMLText>( _textPool );
-        returnNode = text;
-        returnNode->_parseLineNum = _parseCurLineNum;
-        p += cdataHeaderLen;
-        text->SetCData( true );
-    }
-    else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {
-        returnNode = CreateUnlinkedNode<XMLUnknown>( _commentPool );
-        returnNode->_parseLineNum = _parseCurLineNum;
-        p += dtdHeaderLen;
-    }
-    else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) {
-        returnNode =  CreateUnlinkedNode<XMLElement>( _elementPool );
-        returnNode->_parseLineNum = _parseCurLineNum;
-        p += elementHeaderLen;
-    }
-    else {
-        returnNode = CreateUnlinkedNode<XMLText>( _textPool );
-        returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character
-        p = start;	// Back it up, all the text counts.
-        _parseCurLineNum = startLine;
-    }
-
-    TIXMLASSERT( returnNode );
-    TIXMLASSERT( p );
-    *node = returnNode;
-    return p;
-}
-
-
-bool XMLDocument::Accept( XMLVisitor* visitor ) const
-{
-    TIXMLASSERT( visitor );
-    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 ),
-    _parseLineNum( 0 ),
-    _firstChild( 0 ), _lastChild( 0 ),
-    _prev( 0 ), _next( 0 ),
-	_userData( 0 ),
-    _memPool( 0 )
-{
-}
-
-
-XMLNode::~XMLNode()
-{
-    DeleteChildren();
-    if ( _parent ) {
-        _parent->Unlink( this );
-    }
-}
-
-const char* XMLNode::Value() const 
-{
-    // Edge case: XMLDocuments don't have a Value. Return null.
-    if ( this->ToDocument() )
-        return 0;
-    return _value.GetStr();
-}
-
-void XMLNode::SetValue( const char* str, bool staticMem )
-{
-    if ( staticMem ) {
-        _value.SetInternedStr( str );
-    }
-    else {
-        _value.SetStr( str );
-    }
-}
-
-XMLNode* XMLNode::DeepClone(XMLDocument* target) const
-{
-	XMLNode* clone = this->ShallowClone(target);
-	if (!clone) return 0;
-
-	for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) {
-		XMLNode* childClone = child->DeepClone(target);
-		TIXMLASSERT(childClone);
-		clone->InsertEndChild(childClone);
-	}
-	return clone;
-}
-
-void XMLNode::DeleteChildren()
-{
-    while( _firstChild ) {
-        TIXMLASSERT( _lastChild );
-        DeleteChild( _firstChild );
-    }
-    _firstChild = _lastChild = 0;
-}
-
-
-void XMLNode::Unlink( XMLNode* child )
-{
-    TIXMLASSERT( child );
-    TIXMLASSERT( child->_document == _document );
-    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->_next = 0;
-	child->_prev = 0;
-	child->_parent = 0;
-}
-
-
-void XMLNode::DeleteChild( XMLNode* node )
-{
-    TIXMLASSERT( node );
-    TIXMLASSERT( node->_document == _document );
-    TIXMLASSERT( node->_parent == this );
-    Unlink( node );
-	TIXMLASSERT(node->_prev == 0);
-	TIXMLASSERT(node->_next == 0);
-	TIXMLASSERT(node->_parent == 0);
-    DeleteNode( node );
-}
-
-
-XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
-{
-    TIXMLASSERT( addThis );
-    if ( addThis->_document != _document ) {
-        TIXMLASSERT( false );
-        return 0;
-    }
-    InsertChildPreamble( 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 )
-{
-    TIXMLASSERT( addThis );
-    if ( addThis->_document != _document ) {
-        TIXMLASSERT( false );
-        return 0;
-    }
-    InsertChildPreamble( 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( addThis );
-    if ( addThis->_document != _document ) {
-        TIXMLASSERT( false );
-        return 0;
-    }
-
-    TIXMLASSERT( afterThis );
-
-    if ( afterThis->_parent != this ) {
-        TIXMLASSERT( false );
-        return 0;
-    }
-
-    if ( afterThis->_next == 0 ) {
-        // The last node or the only node.
-        return InsertEndChild( addThis );
-    }
-    InsertChildPreamble( 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* name ) const
-{
-    for( const XMLNode* node = _firstChild; node; node = node->_next ) {
-        const XMLElement* element = node->ToElementWithName( name );
-        if ( element ) {
-            return element;
-        }
-    }
-    return 0;
-}
-
-
-const XMLElement* XMLNode::LastChildElement( const char* name ) const
-{
-    for( const XMLNode* node = _lastChild; node; node = node->_prev ) {
-        const XMLElement* element = node->ToElementWithName( name );
-        if ( element ) {
-            return element;
-        }
-    }
-    return 0;
-}
-
-
-const XMLElement* XMLNode::NextSiblingElement( const char* name ) const
-{
-    for( const XMLNode* node = _next; node; node = node->_next ) {
-        const XMLElement* element = node->ToElementWithName( name );
-        if ( element ) {
-            return element;
-        }
-    }
-    return 0;
-}
-
-
-const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const
-{
-    for( const XMLNode* node = _prev; node; node = node->_prev ) {
-        const XMLElement* element = node->ToElementWithName( name );
-        if ( element ) {
-            return element;
-        }
-    }
-    return 0;
-}
-
-
-char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
-{
-    // 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 );
-        TIXMLASSERT( p );
-        if ( node == 0 ) {
-            break;
-        }
-
-        int initialLineNum = node->_parseLineNum;
-
-        StrPair endTag;
-        p = node->ParseDeep( p, &endTag, curLineNumPtr );
-        if ( !p ) {
-            DeleteNode( node );
-            if ( !_document->Error() ) {
-                _document->SetError( XML_ERROR_PARSING, 0, 0, initialLineNum);
-            }
-            break;
-        }
-
-        XMLDeclaration* decl = node->ToDeclaration();
-        if ( decl ) {
-            // Declarations are only allowed at document level
-            bool wellLocated = ( ToDocument() != 0 );
-            if ( wellLocated ) {
-                // Multiple declarations are allowed but all declarations
-                // must occur before anything else
-                for ( const XMLNode* existingNode = _document->FirstChild(); existingNode; existingNode = existingNode->NextSibling() ) {
-                    if ( !existingNode->ToDeclaration() ) {
-                        wellLocated = false;
-                        break;
-                    }
-                }
-            }
-            if ( !wellLocated ) {
-                _document->SetError( XML_ERROR_PARSING_DECLARATION, decl->Value(), 0, initialLineNum);
-                DeleteNode( node );
-                break;
-            }
-        }
-
-        XMLElement* ele = node->ToElement();
-        if ( ele ) {
-            // We read the end tag. Return it to the parent.
-            if ( ele->ClosingType() == XMLElement::CLOSING ) {
-                if ( parentEndTag ) {
-                    ele->_value.TransferTo( parentEndTag );
-                }
-                node->_memPool->SetTracked();   // created and then immediately deleted.
-                DeleteNode( node );
-                return p;
-            }
-
-            // Handle an end tag returned to this level.
-            // And handle a bunch of annoying errors.
-            bool mismatch = false;
-            if ( endTag.Empty() ) {
-                if ( ele->ClosingType() == XMLElement::OPEN ) {
-                    mismatch = true;
-                }
-            }
-            else {
-                if ( ele->ClosingType() != XMLElement::OPEN ) {
-                    mismatch = true;
-                }
-                else if ( !XMLUtil::StringEqual( endTag.GetStr(), ele->Name() ) ) {
-                    mismatch = true;
-                }
-            }
-            if ( mismatch ) {
-                _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, ele->Name(), 0, initialLineNum);
-                DeleteNode( node );
-                break;
-            }
-        }
-        InsertEndChild( node );
-    }
-    return 0;
-}
-
-/*static*/ void XMLNode::DeleteNode( XMLNode* node )
-{
-    if ( node == 0 ) {
-        return;
-    }
-	TIXMLASSERT(node->_document);
-	if (!node->ToDocument()) {
-		node->_document->MarkInUse(node);
-	}
-
-    MemPool* pool = node->_memPool;
-    node->~XMLNode();
-    pool->Free( node );
-}
-
-void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const
-{
-    TIXMLASSERT( insertThis );
-    TIXMLASSERT( insertThis->_document == _document );
-
-	if (insertThis->_parent) {
-        insertThis->_parent->Unlink( insertThis );
-	}
-	else {
-		insertThis->_document->MarkInUse(insertThis);
-        insertThis->_memPool->SetTracked();
-	}
-}
-
-const XMLElement* XMLNode::ToElementWithName( const char* name ) const
-{
-    const XMLElement* element = this->ToElement();
-    if ( element == 0 ) {
-        return 0;
-    }
-    if ( name == 0 ) {
-        return element;
-    }
-    if ( XMLUtil::StringEqual( element->Name(), name ) ) {
-       return element;
-    }
-    return 0;
-}
-
-// --------- XMLText ---------- //
-char* XMLText::ParseDeep( char* p, StrPair*, int* curLineNumPtr )
-{
-    const char* start = p;
-    if ( this->CData() ) {
-        p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
-        if ( !p ) {
-            _document->SetError( XML_ERROR_PARSING_CDATA, start, 0, _parseLineNum );
-        }
-        return p;
-    }
-    else {
-        int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES;
-        if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) {
-            flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING;
-        }
-
-        p = _value.ParseText( p, "<", flags, curLineNumPtr );
-        if ( p && *p ) {
-            return p-1;
-        }
-        if ( !p ) {
-            _document->SetError( XML_ERROR_PARSING_TEXT, start, 0, _parseLineNum );
-        }
-    }
-    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
-{
-    TIXMLASSERT( compare );
-    const XMLText* text = compare->ToText();
-    return ( text && XMLUtil::StringEqual( text->Value(), Value() ) );
-}
-
-
-bool XMLText::Accept( XMLVisitor* visitor ) const
-{
-    TIXMLASSERT( visitor );
-    return visitor->Visit( *this );
-}
-
-
-// --------- XMLComment ---------- //
-
-XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc )
-{
-}
-
-
-XMLComment::~XMLComment()
-{
-}
-
-
-char* XMLComment::ParseDeep( char* p, StrPair*, int* curLineNumPtr )
-{
-    // Comment parses as text.
-    const char* start = p;
-    p = _value.ParseText( p, "-->", StrPair::COMMENT, curLineNumPtr );
-    if ( p == 0 ) {
-        _document->SetError( XML_ERROR_PARSING_COMMENT, start, 0, _parseLineNum );
-    }
-    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
-{
-    TIXMLASSERT( compare );
-    const XMLComment* comment = compare->ToComment();
-    return ( comment && XMLUtil::StringEqual( comment->Value(), Value() ));
-}
-
-
-bool XMLComment::Accept( XMLVisitor* visitor ) const
-{
-    TIXMLASSERT( visitor );
-    return visitor->Visit( *this );
-}
-
-
-// --------- XMLDeclaration ---------- //
-
-XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc )
-{
-}
-
-
-XMLDeclaration::~XMLDeclaration()
-{
-    //printf( "~XMLDeclaration\n" );
-}
-
-
-char* XMLDeclaration::ParseDeep( char* p, StrPair*, int* curLineNumPtr )
-{
-    // Declaration parses as text.
-    const char* start = p;
-    p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
-    if ( p == 0 ) {
-        _document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0, _parseLineNum );
-    }
-    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
-{
-    TIXMLASSERT( compare );
-    const XMLDeclaration* declaration = compare->ToDeclaration();
-    return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() ));
-}
-
-
-
-bool XMLDeclaration::Accept( XMLVisitor* visitor ) const
-{
-    TIXMLASSERT( visitor );
-    return visitor->Visit( *this );
-}
-
-// --------- XMLUnknown ---------- //
-
-XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc )
-{
-}
-
-
-XMLUnknown::~XMLUnknown()
-{
-}
-
-
-char* XMLUnknown::ParseDeep( char* p, StrPair*, int* curLineNumPtr )
-{
-    // Unknown parses as text.
-    const char* start = p;
-
-    p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
-    if ( !p ) {
-        _document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0, _parseLineNum );
-    }
-    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
-{
-    TIXMLASSERT( compare );
-    const XMLUnknown* unknown = compare->ToUnknown();
-    return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() ));
-}
-
-
-bool XMLUnknown::Accept( XMLVisitor* visitor ) const
-{
-    TIXMLASSERT( visitor );
-    return visitor->Visit( *this );
-}
-
-// --------- XMLAttribute ---------- //
-
-const char* XMLAttribute::Name() const 
-{
-    return _name.GetStr();
-}
-
-const char* XMLAttribute::Value() const 
-{
-    return _value.GetStr();
-}
-
-char* XMLAttribute::ParseDeep( char* p, bool processEntities, int* curLineNumPtr )
-{
-    // 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, curLineNumPtr );
-    if ( *p != '=' ) {
-        return 0;
-    }
-
-    ++p;	// move up to opening quote
-    p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr );
-    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, curLineNumPtr );
-    return p;
-}
-
-
-void XMLAttribute::SetName( const char* n )
-{
-    _name.SetStr( n );
-}
-
-
-XMLError XMLAttribute::QueryIntValue( int* value ) const
-{
-    if ( XMLUtil::ToInt( Value(), value )) {
-        return XML_SUCCESS;
-    }
-    return XML_WRONG_ATTRIBUTE_TYPE;
-}
-
-
-XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const
-{
-    if ( XMLUtil::ToUnsigned( Value(), value )) {
-        return XML_SUCCESS;
-    }
-    return XML_WRONG_ATTRIBUTE_TYPE;
-}
-
-
-XMLError XMLAttribute::QueryInt64Value(int64_t* value) const
-{
-	if (XMLUtil::ToInt64(Value(), value)) {
-		return XML_SUCCESS;
-	}
-	return XML_WRONG_ATTRIBUTE_TYPE;
-}
-
-
-XMLError XMLAttribute::QueryBoolValue( bool* value ) const
-{
-    if ( XMLUtil::ToBool( Value(), value )) {
-        return XML_SUCCESS;
-    }
-    return XML_WRONG_ATTRIBUTE_TYPE;
-}
-
-
-XMLError XMLAttribute::QueryFloatValue( float* value ) const
-{
-    if ( XMLUtil::ToFloat( Value(), value )) {
-        return XML_SUCCESS;
-    }
-    return XML_WRONG_ATTRIBUTE_TYPE;
-}
-
-
-XMLError XMLAttribute::QueryDoubleValue( double* value ) const
-{
-    if ( XMLUtil::ToDouble( Value(), value )) {
-        return XML_SUCCESS;
-    }
-    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(int64_t 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( OPEN ),
-    _rootAttribute( 0 )
-{
-}
-
-
-XMLElement::~XMLElement()
-{
-    while( _rootAttribute ) {
-        XMLAttribute* next = _rootAttribute->_next;
-        DeleteAttribute( _rootAttribute );
-        _rootAttribute = next;
-    }
-}
-
-
-const XMLAttribute* XMLElement::FindAttribute( const char* name ) const
-{
-    for( XMLAttribute* 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;
-}
-
-int XMLElement::IntAttribute(const char* name, int defaultValue) const 
-{
-	int i = defaultValue;
-	QueryIntAttribute(name, &i);
-	return i;
-}
-
-unsigned XMLElement::UnsignedAttribute(const char* name, unsigned defaultValue) const 
-{
-	unsigned i = defaultValue;
-	QueryUnsignedAttribute(name, &i);
-	return i;
-}
-
-int64_t XMLElement::Int64Attribute(const char* name, int64_t defaultValue) const 
-{
-	int64_t i = defaultValue;
-	QueryInt64Attribute(name, &i);
-	return i;
-}
-
-bool XMLElement::BoolAttribute(const char* name, bool defaultValue) const 
-{
-	bool b = defaultValue;
-	QueryBoolAttribute(name, &b);
-	return b;
-}
-
-double XMLElement::DoubleAttribute(const char* name, double defaultValue) const 
-{
-	double d = defaultValue;
-	QueryDoubleAttribute(name, &d);
-	return d;
-}
-
-float XMLElement::FloatAttribute(const char* name, float defaultValue) const 
-{
-	float f = defaultValue;
-	QueryFloatAttribute(name, &f);
-	return f;
-}
-
-const char* XMLElement::GetText() const
-{
-    if ( FirstChild() && FirstChild()->ToText() ) {
-        return FirstChild()->Value();
-    }
-    return 0;
-}
-
-
-void	XMLElement::SetText( const char* inText )
-{
-	if ( FirstChild() && FirstChild()->ToText() )
-		FirstChild()->SetValue( inText );
-	else {
-		XMLText*	theText = GetDocument()->NewText( inText );
-		InsertFirstChild( theText );
-	}
-}
-
-
-void XMLElement::SetText( int v ) 
-{
-    char buf[BUF_SIZE];
-    XMLUtil::ToStr( v, buf, BUF_SIZE );
-    SetText( buf );
-}
-
-
-void XMLElement::SetText( unsigned v ) 
-{
-    char buf[BUF_SIZE];
-    XMLUtil::ToStr( v, buf, BUF_SIZE );
-    SetText( buf );
-}
-
-
-void XMLElement::SetText(int64_t v)
-{
-	char buf[BUF_SIZE];
-	XMLUtil::ToStr(v, buf, BUF_SIZE);
-	SetText(buf);
-}
-
-
-void XMLElement::SetText( bool v )
-{
-    char buf[BUF_SIZE];
-    XMLUtil::ToStr( v, buf, BUF_SIZE );
-    SetText( buf );
-}
-
-
-void XMLElement::SetText( float v ) 
-{
-    char buf[BUF_SIZE];
-    XMLUtil::ToStr( v, buf, BUF_SIZE );
-    SetText( buf );
-}
-
-
-void XMLElement::SetText( double v ) 
-{
-    char buf[BUF_SIZE];
-    XMLUtil::ToStr( v, buf, BUF_SIZE );
-    SetText( buf );
-}
-
-
-XMLError XMLElement::QueryIntText( int* ival ) const
-{
-    if ( FirstChild() && FirstChild()->ToText() ) {
-        const char* t = FirstChild()->Value();
-        if ( XMLUtil::ToInt( t, ival ) ) {
-            return XML_SUCCESS;
-        }
-        return XML_CAN_NOT_CONVERT_TEXT;
-    }
-    return XML_NO_TEXT_NODE;
-}
-
-
-XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const
-{
-    if ( FirstChild() && FirstChild()->ToText() ) {
-        const char* t = FirstChild()->Value();
-        if ( XMLUtil::ToUnsigned( t, uval ) ) {
-            return XML_SUCCESS;
-        }
-        return XML_CAN_NOT_CONVERT_TEXT;
-    }
-    return XML_NO_TEXT_NODE;
-}
-
-
-XMLError XMLElement::QueryInt64Text(int64_t* ival) const
-{
-	if (FirstChild() && FirstChild()->ToText()) {
-		const char* t = FirstChild()->Value();
-		if (XMLUtil::ToInt64(t, ival)) {
-			return XML_SUCCESS;
-		}
-		return XML_CAN_NOT_CONVERT_TEXT;
-	}
-	return XML_NO_TEXT_NODE;
-}
-
-
-XMLError XMLElement::QueryBoolText( bool* bval ) const
-{
-    if ( FirstChild() && FirstChild()->ToText() ) {
-        const char* t = FirstChild()->Value();
-        if ( XMLUtil::ToBool( t, bval ) ) {
-            return XML_SUCCESS;
-        }
-        return XML_CAN_NOT_CONVERT_TEXT;
-    }
-    return XML_NO_TEXT_NODE;
-}
-
-
-XMLError XMLElement::QueryDoubleText( double* dval ) const
-{
-    if ( FirstChild() && FirstChild()->ToText() ) {
-        const char* t = FirstChild()->Value();
-        if ( XMLUtil::ToDouble( t, dval ) ) {
-            return XML_SUCCESS;
-        }
-        return XML_CAN_NOT_CONVERT_TEXT;
-    }
-    return XML_NO_TEXT_NODE;
-}
-
-
-XMLError XMLElement::QueryFloatText( float* fval ) const
-{
-    if ( FirstChild() && FirstChild()->ToText() ) {
-        const char* t = FirstChild()->Value();
-        if ( XMLUtil::ToFloat( t, fval ) ) {
-            return XML_SUCCESS;
-        }
-        return XML_CAN_NOT_CONVERT_TEXT;
-    }
-    return XML_NO_TEXT_NODE;
-}
-
-int XMLElement::IntText(int defaultValue) const
-{
-	int i = defaultValue;
-	QueryIntText(&i);
-	return i;
-}
-
-unsigned XMLElement::UnsignedText(unsigned defaultValue) const
-{
-	unsigned i = defaultValue;
-	QueryUnsignedText(&i);
-	return i;
-}
-
-int64_t XMLElement::Int64Text(int64_t defaultValue) const
-{
-	int64_t i = defaultValue;
-	QueryInt64Text(&i);
-	return i;
-}
-
-bool XMLElement::BoolText(bool defaultValue) const
-{
-	bool b = defaultValue;
-	QueryBoolText(&b);
-	return b;
-}
-
-double XMLElement::DoubleText(double defaultValue) const
-{
-	double d = defaultValue;
-	QueryDoubleText(&d);
-	return d;
-}
-
-float XMLElement::FloatText(float defaultValue) const
-{
-	float f = defaultValue;
-	QueryFloatText(&f);
-	return f;
-}
-
-
-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 = CreateAttribute();
-        TIXMLASSERT( attrib );
-        if ( last ) {
-            TIXMLASSERT( last->_next == 0 );
-            last->_next = attrib;
-        }
-        else {
-            TIXMLASSERT( _rootAttribute == 0 );
-            _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;
-            }
-            DeleteAttribute( a );
-            break;
-        }
-        prev = a;
-    }
-}
-
-
-char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr )
-{
-    const char* start = p;
-    XMLAttribute* prevAttribute = 0;
-
-    // Read the attributes.
-    while( p ) {
-        p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr );
-        if ( !(*p) ) {
-            _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name(), _parseLineNum );
-            return 0;
-        }
-
-        // attribute.
-        if (XMLUtil::IsNameStartChar( *p ) ) {
-            XMLAttribute* attrib = CreateAttribute();
-            TIXMLASSERT( attrib );
-            attrib->_parseLineNum = _document->_parseCurLineNum;
-
-            int attrLineNum = attrib->_parseLineNum;
-
-            p = attrib->ParseDeep( p, _document->ProcessEntities(), curLineNumPtr );
-            if ( !p || Attribute( attrib->Name() ) ) {
-                DeleteAttribute( attrib );
-                _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p, attrLineNum );
-                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 ) {
-                TIXMLASSERT( prevAttribute->_next == 0 );
-                prevAttribute->_next = attrib;
-            }
-            else {
-                TIXMLASSERT( _rootAttribute == 0 );
-                _rootAttribute = attrib;
-            }
-            prevAttribute = attrib;
-        }
-        // end of the tag
-        else if ( *p == '>' ) {
-            ++p;
-            break;
-        }
-        // end of the tag
-        else if ( *p == '/' && *(p+1) == '>' ) {
-            _closingType = CLOSED;
-            return p+2;	// done; sealed element.
-        }
-        else {
-            _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p, _parseLineNum );
-            return 0;
-        }
-    }
-    return p;
-}
-
-void XMLElement::DeleteAttribute( XMLAttribute* attribute )
-{
-    if ( attribute == 0 ) {
-        return;
-    }
-    MemPool* pool = attribute->_memPool;
-    attribute->~XMLAttribute();
-    pool->Free( attribute );
-}
-
-XMLAttribute* XMLElement::CreateAttribute()
-{
-    TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() );
-    XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();
-    TIXMLASSERT( attrib );
-    attrib->_memPool = &_document->_attributePool;
-    attrib->_memPool->SetTracked();
-    return attrib;
-}
-
-//
-//	<ele></ele>
-//	<ele>foo<b>bar</b></ele>
-//
-char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
-{
-    // Read the element name.
-    p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr );
-
-    // 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, curLineNumPtr );
-    if ( !p || !*p || _closingType != OPEN ) {
-        return p;
-    }
-
-    p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr );
-    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
-{
-    TIXMLASSERT( compare );
-    const XMLElement* other = compare->ToElement();
-    if ( other && XMLUtil::StringEqual( other->Name(), Name() )) {
-
-        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
-{
-    TIXMLASSERT( visitor );
-    if ( visitor->VisitEnter( *this, _rootAttribute ) ) {
-        for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) {
-            if ( !node->Accept( visitor ) ) {
-                break;
-            }
-        }
-    }
-    return visitor->VisitExit( *this );
-}
-
-
-// --------- XMLDocument ----------- //
-
-// Warning: List must match 'enum XMLError'
-const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = {
-    "XML_SUCCESS",
-    "XML_NO_ATTRIBUTE",
-    "XML_WRONG_ATTRIBUTE_TYPE",
-    "XML_ERROR_FILE_NOT_FOUND",
-    "XML_ERROR_FILE_COULD_NOT_BE_OPENED",
-    "XML_ERROR_FILE_READ_ERROR",
-    "UNUSED_XML_ERROR_ELEMENT_MISMATCH",
-    "XML_ERROR_PARSING_ELEMENT",
-    "XML_ERROR_PARSING_ATTRIBUTE",
-    "UNUSED_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"
-};
-
-
-XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) :
-    XMLNode( 0 ),
-    _writeBOM( false ),
-    _processEntities( processEntities ),
-    _errorID(XML_SUCCESS),
-    _whitespaceMode( whitespaceMode ),
-    _errorLineNum( 0 ),
-    _charBuffer( 0 ),
-    _parseCurLineNum( 0 )
-{
-    // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+)
-    _document = this;
-}
-
-
-XMLDocument::~XMLDocument()
-{
-    Clear();
-}
-
-
-void XMLDocument::MarkInUse(XMLNode* node)
-{
-	TIXMLASSERT(node);
-	TIXMLASSERT(node->_parent == 0);
-
-	for (int i = 0; i < _unlinked.Size(); ++i) {
-		if (node == _unlinked[i]) {
-			_unlinked.SwapRemove(i);
-			break;
-		}
-	}
-}
-
-void XMLDocument::Clear()
-{
-    DeleteChildren();
-	while( _unlinked.Size()) {
-		DeleteNode(_unlinked[0]);	// Will remove from _unlinked as part of delete.
-	}
-
-#ifdef TINYXML2_DEBUG
-    const bool hadError = Error();
-#endif
-    ClearError();
-
-    delete [] _charBuffer;
-    _charBuffer = 0;
-
-#if 0
-    _textPool.Trace( "text" );
-    _elementPool.Trace( "element" );
-    _commentPool.Trace( "comment" );
-    _attributePool.Trace( "attribute" );
-#endif
-    
-#ifdef TINYXML2_DEBUG
-    if ( !hadError ) {
-        TIXMLASSERT( _elementPool.CurrentAllocs()   == _elementPool.Untracked() );
-        TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() );
-        TIXMLASSERT( _textPool.CurrentAllocs()      == _textPool.Untracked() );
-        TIXMLASSERT( _commentPool.CurrentAllocs()   == _commentPool.Untracked() );
-    }
-#endif
-}
-
-
-void XMLDocument::DeepCopy(XMLDocument* target)
-{
-	TIXMLASSERT(target);
-    if (target == this) {
-        return; // technically success - a no-op.
-    }
-
-	target->Clear();
-	for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) {
-		target->InsertEndChild(node->DeepClone(target));
-	}
-}
-
-XMLElement* XMLDocument::NewElement( const char* name )
-{
-    XMLElement* ele = CreateUnlinkedNode<XMLElement>( _elementPool );
-    ele->SetName( name );
-    return ele;
-}
-
-
-XMLComment* XMLDocument::NewComment( const char* str )
-{
-    XMLComment* comment = CreateUnlinkedNode<XMLComment>( _commentPool );
-    comment->SetValue( str );
-    return comment;
-}
-
-
-XMLText* XMLDocument::NewText( const char* str )
-{
-    XMLText* text = CreateUnlinkedNode<XMLText>( _textPool );
-    text->SetValue( str );
-    return text;
-}
-
-
-XMLDeclaration* XMLDocument::NewDeclaration( const char* str )
-{
-    XMLDeclaration* dec = CreateUnlinkedNode<XMLDeclaration>( _commentPool );
-    dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" );
-    return dec;
-}
-
-
-XMLUnknown* XMLDocument::NewUnknown( const char* str )
-{
-    XMLUnknown* unk = CreateUnlinkedNode<XMLUnknown>( _commentPool );
-    unk->SetValue( str );
-    return unk;
-}
-
-static FILE* callfopen( const char* filepath, const char* mode )
-{
-    TIXMLASSERT( filepath );
-    TIXMLASSERT( mode );
-#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
-    FILE* fp = 0;
-    errno_t err = fopen_s( &fp, filepath, mode );
-    if ( err ) {
-        return 0;
-    }
-#else
-    FILE* fp = fopen( filepath, mode );
-#endif
-    return fp;
-}
-    
-void XMLDocument::DeleteNode( XMLNode* node )	{
-    TIXMLASSERT( node );
-    TIXMLASSERT(node->_document == this );
-    if (node->_parent) {
-        node->_parent->DeleteChild( node );
-    }
-    else {
-        // Isn't in the tree.
-        // Use the parent delete.
-        // Also, we need to mark it tracked: we 'know'
-        // it was never used.
-        node->_memPool->SetTracked();
-        // Call the static XMLNode version:
-        XMLNode::DeleteNode(node);
-    }
-}
-
-
-XMLError XMLDocument::LoadFile( const char* filename )
-{
-    Clear();
-    FILE* fp = callfopen( filename, "rb" );
-    if ( !fp ) {
-        SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0, 0 );
-        return _errorID;
-    }
-    LoadFile( fp );
-    fclose( fp );
-    return _errorID;
-}
-
-// This is likely overengineered template art to have a check that unsigned long value incremented
-// by one still fits into size_t. If size_t type is larger than unsigned long type
-// (x86_64-w64-mingw32 target) then the check is redundant and gcc and clang emit
-// -Wtype-limits warning. This piece makes the compiler select code with a check when a check
-// is useful and code with no check when a check is redundant depending on how size_t and unsigned long
-// types sizes relate to each other.
-template
-<bool = (sizeof(unsigned long) >= sizeof(size_t))>
-struct LongFitsIntoSizeTMinusOne {
-    static bool Fits( unsigned long value )
-    {
-        return value < (size_t)-1;
-    }
-};
-
-template <>
-struct LongFitsIntoSizeTMinusOne<false> {
-    static bool Fits( unsigned long )
-    {
-        return true;
-    }
-};
-
-XMLError XMLDocument::LoadFile( FILE* fp )
-{
-    Clear();
-
-    fseek( fp, 0, SEEK_SET );
-    if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) {
-        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0, 0 );
-        return _errorID;
-    }
-
-    fseek( fp, 0, SEEK_END );
-    const long filelength = ftell( fp );
-    fseek( fp, 0, SEEK_SET );
-    if ( filelength == -1L ) {
-        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0, 0 );
-        return _errorID;
-    }
-    TIXMLASSERT( filelength >= 0 );
-
-    if ( !LongFitsIntoSizeTMinusOne<>::Fits( filelength ) ) {
-        // Cannot handle files which won't fit in buffer together with null terminator
-        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0, 0 );
-        return _errorID;
-    }
-
-    if ( filelength == 0 ) {
-        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0, 0 );
-        return _errorID;
-    }
-
-    const size_t size = filelength;
-    TIXMLASSERT( _charBuffer == 0 );
-    _charBuffer = new char[size+1];
-    size_t read = fread( _charBuffer, 1, size, fp );
-    if ( read != size ) {
-        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0, 0 );
-        return _errorID;
-    }
-
-    _charBuffer[size] = 0;
-
-    Parse();
-    return _errorID;
-}
-
-
-XMLError XMLDocument::SaveFile( const char* filename, bool compact )
-{
-    FILE* fp = callfopen( filename, "w" );
-    if ( !fp ) {
-        SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0, 0 );
-        return _errorID;
-    }
-    SaveFile(fp, compact);
-    fclose( fp );
-    return _errorID;
-}
-
-
-XMLError XMLDocument::SaveFile( FILE* fp, bool compact )
-{
-    // Clear any error from the last save, otherwise it will get reported
-    // for *this* call.
-    ClearError();
-    XMLPrinter stream( fp, compact );
-    Print( &stream );
-    return _errorID;
-}
-
-
-XMLError XMLDocument::Parse( const char* p, size_t len )
-{
-    Clear();
-
-    if ( len == 0 || !p || !*p ) {
-        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0, 0 );
-        return _errorID;
-    }
-    if ( len == (size_t)(-1) ) {
-        len = strlen( p );
-    }
-    TIXMLASSERT( _charBuffer == 0 );
-    _charBuffer = new char[ len+1 ];
-    memcpy( _charBuffer, p, len );
-    _charBuffer[len] = 0;
-
-    Parse();
-    if ( Error() ) {
-        // clean up now essentially dangling memory.
-        // and the parse fail can put objects in the
-        // pools that are dead and inaccessible.
-        DeleteChildren();
-        _elementPool.Clear();
-        _attributePool.Clear();
-        _textPool.Clear();
-        _commentPool.Clear();
-    }
-    return _errorID;
-}
-
-
-void XMLDocument::Print( XMLPrinter* streamer ) const
-{
-    if ( streamer ) {
-        Accept( streamer );
-    }
-    else {
-        XMLPrinter stdoutStreamer( stdout );
-        Accept( &stdoutStreamer );
-    }
-}
-
-
-void XMLDocument::SetError( XMLError error, const char* str1, const char* str2, int lineNum )
-{
-    TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT );
-    _errorID = error;
-	
-	_errorStr1.Reset();
-	_errorStr2.Reset();
-    _errorLineNum = lineNum;
-
-	if (str1)
-		_errorStr1.SetStr(str1);
-	if (str2)
-		_errorStr2.SetStr(str2);
-}
-
-/*static*/ const char* XMLDocument::ErrorIDToName(XMLError errorID)
-{
-	TIXMLASSERT( errorID >= 0 && errorID < XML_ERROR_COUNT );
-    const char* errorName = _errorNames[errorID];
-    TIXMLASSERT( errorName && errorName[0] );
-    return errorName;
-}
-
-const char* XMLDocument::GetErrorStr1() const 
-{
-	return _errorStr1.GetStr();
-}
-
-const char* XMLDocument::GetErrorStr2() const 
-{
-	return _errorStr2.GetStr();
-}
-
-const char* XMLDocument::ErrorName() const
-{
-    return ErrorIDToName(_errorID);
-}
-
-void XMLDocument::PrintError() const
-{
-    if ( Error() ) {
-        static const int LEN = 20;
-        char buf1[LEN] = { 0 };
-        char buf2[LEN] = { 0 };
-
-        if ( !_errorStr1.Empty() ) {
-            TIXML_SNPRINTF( buf1, LEN, "%s", _errorStr1.GetStr() );
-        }
-        if ( !_errorStr2.Empty() ) {
-            TIXML_SNPRINTF( buf2, LEN, "%s", _errorStr2.GetStr() );
-        }
-
-        // Should check INT_MIN <= _errorID && _errorId <= INT_MAX, but that
-        // causes a clang "always true" -Wtautological-constant-out-of-range-compare warning
-        TIXMLASSERT( 0 <= _errorID && XML_ERROR_COUNT - 1 <= INT_MAX );
-        printf( "XMLDocument error id=%d '%s' str1=%s str2=%s line=%d\n",
-                static_cast<int>( _errorID ), ErrorName(), buf1, buf2, _errorLineNum );
-    }
-}
-
-void XMLDocument::Parse()
-{
-    TIXMLASSERT( NoChildren() ); // Clear() must have been called previously
-    TIXMLASSERT( _charBuffer );
-    _parseCurLineNum = 1;
-    _parseLineNum = 1;
-    char* p = _charBuffer;
-    p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum );
-    p = const_cast<char*>( XMLUtil::ReadBOM( p, &_writeBOM ) );
-    if ( !*p ) {
-        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0, 0 );
-        return;
-    }
-    ParseDeep(p, 0, &_parseCurLineNum );
-}
-
-XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
-    _elementJustOpened( false ),
-    _firstElement( true ),
-    _fp( file ),
-    _depth( depth ),
-    _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 ) {
-        const char entityValue = entities[i].value;
-        TIXMLASSERT( ((unsigned char)entityValue) < ENTITY_RANGE );
-        _entityFlag[ (unsigned char)entityValue ] = true;
-    }
-    _restrictedEntityFlag[(unsigned char)'&'] = true;
-    _restrictedEntityFlag[(unsigned char)'<'] = true;
-    _restrictedEntityFlag[(unsigned char)'>'] = 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 {
-        const int len = TIXML_VSCPRINTF( format, va );
-        // Close out and re-start the va-args
-        va_end( va );
-        TIXMLASSERT( len >= 0 );
-        va_start( va, format );
-        TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 );
-        char* p = _buffer.PushArr( len ) - 1;	// back up over the null terminator.
-		TIXML_VSNPRINTF( p, len+1, format, va );
-    }
-    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;
-
-    if ( _processEntities ) {
-        const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag;
-        while ( *q ) {
-            TIXMLASSERT( p <= 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 char)(*q)] ) {
-                    while ( p < q ) {
-                        const size_t delta = q - p;
-                        // %.*s accepts type int as "precision"
-                        const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta;
-                        Print( "%.*s", toPrint, p );
-                        p += toPrint;
-                    }
-                    bool entityPatternPrinted = false;
-                    for( int i=0; i<NUM_ENTITIES; ++i ) {
-                        if ( entities[i].value == *q ) {
-                            Print( "&%s;", entities[i].pattern );
-                            entityPatternPrinted = true;
-                            break;
-                        }
-                    }
-                    if ( !entityPatternPrinted ) {
-                        // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release
-                        TIXMLASSERT( false );
-                    }
-                    ++p;
-                }
-            }
-            ++q;
-            TIXMLASSERT( p <= q );
-        }
-    }
-    // Flush the remaining string. This will be the entire
-    // string if an entity wasn't found.
-    TIXMLASSERT( p <= q );
-    if ( !_processEntities || ( p < q ) ) {
-        Print( "%s", p );
-    }
-}
-
-
-void XMLPrinter::PushHeader( bool writeBOM, bool writeDec )
-{
-    if ( writeBOM ) {
-        static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
-        Print( "%s", bom );
-    }
-    if ( writeDec ) {
-        PushDeclaration( "xml version=\"1.0\"" );
-    }
-}
-
-
-void XMLPrinter::OpenElement( const char* name, bool compactMode )
-{
-    SealElementIfJustOpened();
-    _stack.Push( name );
-
-    if ( _textDepth < 0 && !_firstElement && !compactMode ) {
-        Print( "\n" );
-    }
-    if ( !compactMode ) {
-        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, int64_t 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( bool compactMode )
-{
-    --_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::SealElementIfJustOpened()
-{
-    if ( !_elementJustOpened ) {
-        return;
-    }
-    _elementJustOpened = false;
-    Print( ">" );
-}
-
-
-void XMLPrinter::PushText( const char* text, bool cdata )
-{
-    _textDepth = _depth-1;
-
-    SealElementIfJustOpened();
-    if ( cdata ) {
-        Print( "<![CDATA[%s]]>", text );
-    }
-    else {
-        PrintString( text, true );
-    }
-}
-
-void XMLPrinter::PushText( int64_t value )
-{
-    char buf[BUF_SIZE];
-    XMLUtil::ToStr( value, buf, BUF_SIZE );
-    PushText( buf, false );
-}
-
-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 )
-{
-    SealElementIfJustOpened();
-    if ( _textDepth < 0 && !_firstElement && !_compactMode) {
-        Print( "\n" );
-        PrintSpace( _depth );
-    }
-    _firstElement = false;
-    Print( "<!--%s-->", comment );
-}
-
-
-void XMLPrinter::PushDeclaration( const char* value )
-{
-    SealElementIfJustOpened();
-    if ( _textDepth < 0 && !_firstElement && !_compactMode) {
-        Print( "\n" );
-        PrintSpace( _depth );
-    }
-    _firstElement = false;
-    Print( "<?%s?>", value );
-}
-
-
-void XMLPrinter::PushUnknown( const char* value )
-{
-    SealElementIfJustOpened();
-    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 )
-{
-    const XMLElement* parentElem = 0;
-    if ( element.Parent() ) {
-        parentElem = element.Parent()->ToElement();
-    }
-    const bool compactMode = parentElem ? CompactMode( *parentElem ) : _compactMode;
-    OpenElement( element.Name(), compactMode );
-    while ( attribute ) {
-        PushAttribute( attribute->Name(), attribute->Value() );
-        attribute = attribute->Next();
-    }
-    return true;
-}
-
-
-bool XMLPrinter::VisitExit( const XMLElement& element )
-{
-    CloseElement( CompactMode(element) );
-    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;
-}
-
-}   // namespace tinyxml2
-
diff --git a/deps/tinyxml2/tinyxml2.h b/deps/tinyxml2/tinyxml2.h
deleted file mode 100644
index ffe5c4b9..00000000
--- a/deps/tinyxml2/tinyxml2.h
+++ /dev/null
@@ -1,2264 +0,0 @@
-/*
-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
-
-#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
-#   include <ctype.h>
-#   include <limits.h>
-#   include <stdio.h>
-#   include <stdlib.h>
-#   include <string.h>
-#	if defined(__PS3__)
-#		include <stddef.h>
-#	endif
-#else
-#   include <cctype>
-#   include <climits>
-#   include <cstdio>
-#   include <cstdlib>
-#   include <cstring>
-#endif
-#include <stdint.h>
-
-/*
-   TODO: intern strings instead of allocation.
-*/
-/*
-	gcc:
-        g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
-
-    Formatting, Artistic Style:
-        AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
-*/
-
-#if defined( _DEBUG ) || defined (__DEBUG__)
-#   ifndef TINYXML2_DEBUG
-#       define TINYXML2_DEBUG
-#   endif
-#endif
-
-#ifdef _MSC_VER
-#   pragma warning(push)
-#   pragma warning(disable: 4251)
-#endif
-
-#ifdef _WIN32
-#   ifdef TINYXML2_EXPORT
-#       define TINYXML2_LIB __declspec(dllexport)
-#   elif defined(TINYXML2_IMPORT)
-#       define TINYXML2_LIB __declspec(dllimport)
-#   else
-#       define TINYXML2_LIB
-#   endif
-#elif __GNUC__ >= 4
-#   define TINYXML2_LIB __attribute__((visibility("default")))
-#else
-#   define TINYXML2_LIB
-#endif
-
-
-#if defined(TINYXML2_DEBUG)
-#   if defined(_MSC_VER)
-#       // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
-#       define TIXMLASSERT( x )           if ( !((void)0,(x))) { __debugbreak(); }
-#   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
-
-
-/* Versioning, past 1.0.14:
-	http://semver.org/
-*/
-static const int TIXML2_MAJOR_VERSION = 5;
-static const int TIXML2_MINOR_VERSION = 0;
-static const int TIXML2_PATCH_VERSION = 1;
-
-namespace tinyxml2
-{
-class XMLDocument;
-class XMLElement;
-class XMLAttribute;
-class XMLComment;
-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,
-        NEEDS_WHITESPACE_COLLAPSING     = 0x04,
-
-        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 ) {
-        TIXMLASSERT( start );
-        TIXMLASSERT( end );
-        Reset();
-        _start  = start;
-        _end    = end;
-        _flags  = flags | NEEDS_FLUSH;
-    }
-
-    const char* GetStr();
-
-    bool Empty() const {
-        return _start == _end;
-    }
-
-    void SetInternedStr( const char* str ) {
-        Reset();
-        _start = const_cast<char*>(str);
-    }
-
-    void SetStr( const char* str, int flags=0 );
-
-    char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
-    char* ParseName( char* in );
-
-    void TransferTo( StrPair* other );
-	void Reset();
-
-private:
-    void CollapseWhitespace();
-
-    enum {
-        NEEDS_FLUSH = 0x100,
-        NEEDS_DELETE = 0x200
-    };
-
-    int     _flags;
-    char*   _start;
-    char*   _end;
-
-    StrPair( const StrPair& other );	// not supported
-    void operator=( StrPair& other );	// not supported, use TransferTo()
-};
-
-
-/*
-	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 INITIAL_SIZE>
-class DynArray
-{
-public:
-    DynArray() {
-        _mem = _pool;
-        _allocated = INITIAL_SIZE;
-        _size = 0;
-    }
-
-    ~DynArray() {
-        if ( _mem != _pool ) {
-            delete [] _mem;
-        }
-    }
-
-    void Clear() {
-        _size = 0;
-    }
-
-    void Push( T t ) {
-        TIXMLASSERT( _size < INT_MAX );
-        EnsureCapacity( _size+1 );
-        _mem[_size] = t;
-        ++_size;
-    }
-
-    T* PushArr( int count ) {
-        TIXMLASSERT( count >= 0 );
-        TIXMLASSERT( _size <= INT_MAX - count );
-        EnsureCapacity( _size+count );
-        T* ret = &_mem[_size];
-        _size += count;
-        return ret;
-    }
-
-    T Pop() {
-        TIXMLASSERT( _size > 0 );
-        --_size;
-        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];
-    }
-
-    const T& PeekTop() const            {
-        TIXMLASSERT( _size > 0 );
-        return _mem[ _size - 1];
-    }
-
-    int Size() const					{
-        TIXMLASSERT( _size >= 0 );
-        return _size;
-    }
-
-    int Capacity() const				{
-        TIXMLASSERT( _allocated >= INITIAL_SIZE );
-        return _allocated;
-    }
-
-	void SwapRemove(int i) {
-		TIXMLASSERT(i >= 0 && i < _size);
-		TIXMLASSERT(_size > 0);
-		_mem[i] = _mem[_size - 1];
-		--_size;
-	}
-
-    const T* Mem() const				{
-        TIXMLASSERT( _mem );
-        return _mem;
-    }
-
-    T* Mem()							{
-        TIXMLASSERT( _mem );
-        return _mem;
-    }
-
-private:
-    DynArray( const DynArray& ); // not supported
-    void operator=( const DynArray& ); // not supported
-
-    void EnsureCapacity( int cap ) {
-        TIXMLASSERT( cap > 0 );
-        if ( cap > _allocated ) {
-            TIXMLASSERT( cap <= INT_MAX / 2 );
-            int newAllocated = cap * 2;
-            T* newMem = new T[newAllocated];
-            TIXMLASSERT( newAllocated >= _size );
-            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[INITIAL_SIZE];
-    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;
-    virtual void SetTracked() = 0;
-    virtual void Clear() = 0;
-};
-
-
-/*
-	Template child class to create pools of the correct type.
-*/
-template< int ITEM_SIZE >
-class MemPoolT : public MemPool
-{
-public:
-    MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)	{}
-    ~MemPoolT() {
-        Clear();
-    }
-    
-    void Clear() {
-        // Delete the blocks.
-        while( !_blockPtrs.Empty()) {
-            Block* b  = _blockPtrs.Pop();
-            delete b;
-        }
-        _root = 0;
-        _currentAllocs = 0;
-        _nAllocs = 0;
-        _maxAllocs = 0;
-        _nUntracked = 0;
-    }
-
-    virtual int ItemSize() const	{
-        return ITEM_SIZE;
-    }
-    int CurrentAllocs() const		{
-        return _currentAllocs;
-    }
-
-    virtual void* Alloc() {
-        if ( !_root ) {
-            // Need a new block.
-            Block* block = new Block();
-            _blockPtrs.Push( block );
-
-            Item* blockItems = block->items;
-            for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
-                blockItems[i].next = &(blockItems[i + 1]);
-            }
-            blockItems[ITEMS_PER_BLOCK - 1].next = 0;
-            _root = blockItems;
-        }
-        Item* const result = _root;
-        TIXMLASSERT( result != 0 );
-        _root = _root->next;
-
-        ++_currentAllocs;
-        if ( _currentAllocs > _maxAllocs ) {
-            _maxAllocs = _currentAllocs;
-        }
-        ++_nAllocs;
-        ++_nUntracked;
-        return result;
-    }
-    
-    virtual void Free( void* mem ) {
-        if ( !mem ) {
-            return;
-        }
-        --_currentAllocs;
-        Item* item = static_cast<Item*>( mem );
-#ifdef TINYXML2_DEBUG
-        memset( item, 0xfe, sizeof( *item ) );
-#endif
-        item->next = _root;
-        _root = item;
-    }
-    void Trace( const char* name ) {
-        printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
-                name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
-                ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
-    }
-
-    void SetTracked() {
-        --_nUntracked;
-    }
-
-    int Untracked() const {
-        return _nUntracked;
-    }
-
-	// This number is perf sensitive. 4k seems like a good tradeoff on my machine.
-	// The test file is large, 170k.
-	// Release:		VS2010 gcc(no opt)
-	//		1k:		4000
-	//		2k:		4000
-	//		4k:		3900	21000
-	//		16k:	5200
-	//		32k:	4300
-	//		64k:	4000	21000
-    // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
-    // in private part if ITEMS_PER_BLOCK is private
-    enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
-
-private:
-    MemPoolT( const MemPoolT& ); // not supported
-    void operator=( const MemPoolT& ); // not supported
-
-    union Item {
-        Item*   next;
-        char    itemData[ITEM_SIZE];
-    };
-    struct Block {
-        Item items[ITEMS_PER_BLOCK];
-    };
-    DynArray< Block*, 10 > _blockPtrs;
-    Item* _root;
-
-    int _currentAllocs;
-    int _nAllocs;
-    int _maxAllocs;
-    int _nUntracked;
-};
-
-
-
-/**
-	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 siblings</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 XMLDocument, although all nodes support visiting.
-
-	You should never change the document from a callback.
-
-	@sa XMLNode::Accept()
-*/
-class TINYXML2_LIB 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;
-    }
-};
-
-// WARNING: must match XMLDocument::_errorNames[]
-enum XMLError {
-    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,
-    UNUSED_XML_ERROR_ELEMENT_MISMATCH,	// remove at next major version
-    XML_ERROR_PARSING_ELEMENT,
-    XML_ERROR_PARSING_ATTRIBUTE,
-    UNUSED_XML_ERROR_IDENTIFYING_TAG,	// remove at next major version
-    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,
-
-	XML_ERROR_COUNT
-};
-
-
-/*
-	Utility functionality.
-*/
-class TINYXML2_LIB XMLUtil
-{
-public:
-    static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr )	{
-        TIXMLASSERT( p );
-
-        while( IsWhiteSpace(*p) ) {
-            if (curLineNumPtr && *p == '\n') {
-                ++(*curLineNumPtr);
-            }
-            ++p;
-        }
-        TIXMLASSERT( p );
-        return p;
-    }
-    static char* SkipWhiteSpace( char* p, int* curLineNumPtr )				{
-        return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
-    }
-
-    // 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 bool IsWhiteSpace( char p )					{
-        return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
-    }
-    
-    inline static bool IsNameStartChar( unsigned char ch ) {
-        if ( ch >= 128 ) {
-            // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
-            return true;
-        }
-        if ( isalpha( ch ) ) {
-            return true;
-        }
-        return ch == ':' || ch == '_';
-    }
-    
-    inline static bool IsNameChar( unsigned char ch ) {
-        return IsNameStartChar( ch )
-               || isdigit( ch )
-               || ch == '.'
-               || ch == '-';
-    }
-
-    inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {
-        if ( p == q ) {
-            return true;
-        }
-        TIXMLASSERT( p );
-        TIXMLASSERT( q );
-        TIXMLASSERT( nChar >= 0 );
-        return strncmp( p, q, nChar ) == 0;
-    }
-    
-    inline static bool IsUTF8Continuation( char p ) {
-        return ( p & 0x80 ) != 0;
-    }
-
-    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 );
-	static void ToStr(int64_t 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 );
-	static bool ToInt64(const char* str, int64_t* value);
-
-	// Changes what is serialized for a boolean value.
-	// Default to "true" and "false". Shouldn't be changed
-	// unless you have a special testing or compatibility need.
-	// Be careful: static, global, & not thread safe.
-	// Be sure to set static const memory as parameters.
-	static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
-
-private:
-	static const char* writeBoolTrue;
-	static const char* writeBoolFalse;
-};
-
-
-/** 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 TINYXML2_LIB XMLNode
-{
-    friend class XMLDocument;
-    friend class XMLElement;
-public:
-
-    /// Get the XMLDocument that owns this XMLNode.
-    const XMLDocument* GetDocument() const	{
-        TIXMLASSERT( _document );
-        return _document;
-    }
-    /// Get the XMLDocument that owns this XMLNode.
-    XMLDocument* GetDocument()				{
-        TIXMLASSERT( _document );
-        return _document;
-    }
-
-    /// Safely cast to an Element, or null.
-    virtual XMLElement*		ToElement()		{
-        return 0;
-    }
-    /// Safely cast to Text, or null.
-    virtual XMLText*		ToText()		{
-        return 0;
-    }
-    /// Safely cast to a Comment, or null.
-    virtual XMLComment*		ToComment()		{
-        return 0;
-    }
-    /// Safely cast to a Document, or null.
-    virtual XMLDocument*	ToDocument()	{
-        return 0;
-    }
-    /// Safely cast to a Declaration, or null.
-    virtual XMLDeclaration*	ToDeclaration()	{
-        return 0;
-    }
-    /// Safely cast to an Unknown, or null.
-    virtual XMLUnknown*		ToUnknown()		{
-        return 0;
-    }
-
-    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 (NULL is returned, not an empty string)
-    	Element:	name of the element
-    	Comment:	the comment text
-    	Unknown:	the tag contents
-    	Text:		the text string
-    	@endverbatim
-    */
-    const char* Value() const;
-
-    /** Set the Value of an XML node.
-    	@sa Value()
-    */
-    void SetValue( const char* val, bool staticMem=false );
-
-    /// Gets the line number the node is in, if the document was parsed from a file.
-    int GetLineNum() const { return _parseLineNum; }
-
-    /// 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* name = 0 ) const;
-
-    XMLElement* FirstChildElement( const char* name = 0 )	{
-        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
-    }
-
-    /// Get the last child node, or null if none exists.
-    const XMLNode*	LastChild() const						{
-        return _lastChild;
-    }
-
-    XMLNode*		LastChild()								{
-        return _lastChild;
-    }
-
-    /** Get the last child element or optionally the last child
-        element with the specified name.
-    */
-    const XMLElement* LastChildElement( const char* name = 0 ) const;
-
-    XMLElement* LastChildElement( const char* name = 0 )	{
-        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
-    }
-
-    /// 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 optionally supplied name.
-    const XMLElement*	PreviousSiblingElement( const char* name = 0 ) const ;
-
-    XMLElement*	PreviousSiblingElement( const char* name = 0 ) {
-        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
-    }
-
-    /// 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 optionally supplied name.
-    const XMLElement*	NextSiblingElement( const char* name = 0 ) const;
-
-    XMLElement*	NextSiblingElement( const char* name = 0 )	{
-        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
-    }
-
-    /**
-    	Add a child node as the last (right) child.
-		If the child node is already part of the document,
-		it is moved from its old location to the new location.
-		Returns the addThis argument or 0 if the node does not
-		belong to the same document.
-    */
-    XMLNode* InsertEndChild( XMLNode* addThis );
-
-    XMLNode* LinkEndChild( XMLNode* addThis )	{
-        return InsertEndChild( addThis );
-    }
-    /**
-    	Add a child node as the first (left) child.
-		If the child node is already part of the document,
-		it is moved from its old location to the new location.
-		Returns the addThis argument or 0 if the node does not
-		belong to the same document.
-    */
-    XMLNode* InsertFirstChild( XMLNode* addThis );
-    /**
-    	Add a node after the specified child node.
-		If the child node is already part of the document,
-		it is moved from its old location to the new location.
-		Returns the addThis argument or 0 if the afterThis node
-		is not a child of this node, or if the node does not
-		belong to the same document.
-    */
-    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;
-
-	/**
-		Make a copy of this node and all its children.
-
-		If the 'target' is null, then the nodes will
-		be allocated in the current document. If 'target' 
-        is specified, the memory will be allocated is the 
-        specified XMLDocument.
-
-		NOTE: This is probably not the correct tool to 
-		copy a document, since XMLDocuments can have multiple
-		top level XMLNodes. You probably want to use
-        XMLDocument::DeepCopy()
-	*/
-	XMLNode* DeepClone( XMLDocument* target ) const;
-
-    /**
-    	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-2 DOM. Every node in the
-    	XML tree will be conditionally visited and the host will be called back
-    	via the XMLVisitor interface.
-
-    	This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
-    	the XML for the callbacks, so the performance of TinyXML-2 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
-    	XMLPrinter printer;
-    	tinyxmlDoc.Accept( &printer );
-    	const char* xmlcstr = printer.CStr();
-    	@endverbatim
-    */
-    virtual bool Accept( XMLVisitor* visitor ) const = 0;
-
-	/** 
-		Set user data into the XMLNode. TinyXML-2 in 
-		no way processes or interprets user data.
-		It is initially 0.
-	*/
-	void SetUserData(void* userData)	{ _userData = userData; }
-
-	/**
-		Get user data set into the XMLNode. TinyXML-2 in
-		no way processes or interprets user data.
-		It is initially 0.
-	*/
-	void* GetUserData() const			{ return _userData; }
-
-protected:
-    XMLNode( XMLDocument* );
-    virtual ~XMLNode();
-
-    virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
-
-    XMLDocument*	_document;
-    XMLNode*		_parent;
-    mutable StrPair	_value;
-    int             _parseLineNum;
-
-    XMLNode*		_firstChild;
-    XMLNode*		_lastChild;
-
-    XMLNode*		_prev;
-    XMLNode*		_next;
-
-	void*			_userData;
-
-private:
-    MemPool*		_memPool;
-    void Unlink( XMLNode* child );
-    static void DeleteNode( XMLNode* node );
-    void InsertChildPreamble( XMLNode* insertThis ) const;
-    const XMLElement* ToElementWithName( const char* name ) const;
-
-    XMLNode( const XMLNode& );	// not supported
-    XMLNode& operator=( const XMLNode& );	// not supported
-};
-
-
-/** 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 TINYXML2_LIB XMLText : public XMLNode
-{
-    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 )			{
-        _isCData = isCData;
-    }
-    /// Returns true if this is a CDATA text element.
-    bool CData() const						{
-        return _isCData;
-    }
-
-    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
-    virtual bool ShallowEqual( const XMLNode* compare ) const;
-
-protected:
-    XMLText( XMLDocument* doc )	: XMLNode( doc ), _isCData( false )	{}
-    virtual ~XMLText()												{}
-
-    char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
-
-private:
-    bool _isCData;
-
-    XMLText( const XMLText& );	// not supported
-    XMLText& operator=( const XMLText& );	// not supported
-};
-
-
-/** An XML Comment. */
-class TINYXML2_LIB 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;
-
-    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
-    virtual bool ShallowEqual( const XMLNode* compare ) const;
-
-protected:
-    XMLComment( XMLDocument* doc );
-    virtual ~XMLComment();
-
-    char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
-
-private:
-    XMLComment( const XMLComment& );	// not supported
-    XMLComment& operator=( const XMLComment& );	// not supported
-};
-
-
-/** In correct XML the declaration is the first entry in the file.
-	@verbatim
-		<?xml version="1.0" standalone="yes"?>
-	@endverbatim
-
-	TinyXML-2 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 TINYXML2_LIB 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;
-
-    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
-    virtual bool ShallowEqual( const XMLNode* compare ) const;
-
-protected:
-    XMLDeclaration( XMLDocument* doc );
-    virtual ~XMLDeclaration();
-
-    char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
-
-private:
-    XMLDeclaration( const XMLDeclaration& );	// not supported
-    XMLDeclaration& operator=( const XMLDeclaration& );	// not supported
-};
-
-
-/** Any tag that TinyXML-2 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 XMLUnknowns.
-*/
-class TINYXML2_LIB 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;
-
-    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
-    virtual bool ShallowEqual( const XMLNode* compare ) const;
-
-protected:
-    XMLUnknown( XMLDocument* doc );
-    virtual ~XMLUnknown();
-
-    char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
-
-private:
-    XMLUnknown( const XMLUnknown& );	// not supported
-    XMLUnknown& operator=( const XMLUnknown& );	// not supported
-};
-
-
-
-/** 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 TINYXML2_LIB XMLAttribute
-{
-    friend class XMLElement;
-public:
-    /// The name of the attribute.
-    const char* Name() const;
-
-    /// The value of the attribute.
-    const char* Value() const;
-
-    /// Gets the line number the attribute is in, if the document was parsed from a file.
-    int GetLineNum() const { return _parseLineNum; }
-
-    /// The next attribute in the list.
-    const XMLAttribute* Next() const {
-        return _next;
-    }
-
-    /** IntValue 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 QueryIntValue() if you need error checking.
-    */
-	int	IntValue() const {
-		int i = 0;
-		QueryIntValue(&i);
-		return i;
-	}
-
-	int64_t Int64Value() const {
-		int64_t i = 0;
-		QueryInt64Value(&i);
-		return i;
-	}
-
-    /// Query as an unsigned integer. See IntValue()
-    unsigned UnsignedValue() const			{
-        unsigned i=0;
-        QueryUnsignedValue( &i );
-        return i;
-    }
-    /// Query as a boolean. See IntValue()
-    bool	 BoolValue() const				{
-        bool b=false;
-        QueryBoolValue( &b );
-        return b;
-    }
-    /// Query as a double. See IntValue()
-    double 	 DoubleValue() const			{
-        double d=0;
-        QueryDoubleValue( &d );
-        return d;
-    }
-    /// Query as a float. See IntValue()
-    float	 FloatValue() const				{
-        float f=0;
-        QueryFloatValue( &f );
-        return f;
-    }
-
-    /** QueryIntValue interprets the attribute as an integer, and returns the value
-    	in the provided parameter. The function will return XML_SUCCESS on success,
-    	and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
-    */
-    XMLError QueryIntValue( int* value ) const;
-    /// See QueryIntValue
-    XMLError QueryUnsignedValue( unsigned int* value ) const;
-	/// See QueryIntValue
-	XMLError QueryInt64Value(int64_t* value) const;
-	/// See QueryIntValue
-    XMLError QueryBoolValue( bool* value ) const;
-    /// See QueryIntValue
-    XMLError QueryDoubleValue( double* value ) const;
-    /// See QueryIntValue
-    XMLError 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(int64_t 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() : _parseLineNum( 0 ), _next( 0 ), _memPool( 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, int* curLineNumPtr );
-
-    mutable StrPair _name;
-    mutable StrPair _value;
-    int             _parseLineNum;
-    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 TINYXML2_LIB XMLElement : public XMLNode
-{
-    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. The default
-        value will be returned if the attribute isn't present,
-        or if there is an error. (For a method with error
-    	checking, see QueryIntAttribute()).
-    */
-	int IntAttribute(const char* name, int defaultValue = 0) const;
-    /// See IntAttribute()
-	unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
-	/// See IntAttribute()
-	int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
-	/// See IntAttribute()
-	bool BoolAttribute(const char* name, bool defaultValue = false) const;
-    /// See IntAttribute()
-	double DoubleAttribute(const char* name, double defaultValue = 0) const;
-    /// See IntAttribute()
-	float FloatAttribute(const char* name, float defaultValue = 0) const;
-
-    /** Given an attribute name, QueryIntAttribute() returns
-    	XML_SUCCESS, 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
-    */
-    XMLError QueryIntAttribute( const char* name, int* value ) const				{
-        const XMLAttribute* a = FindAttribute( name );
-        if ( !a ) {
-            return XML_NO_ATTRIBUTE;
-        }
-        return a->QueryIntValue( value );
-    }
-
-	/// See QueryIntAttribute()
-    XMLError 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()
-	XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
-		const XMLAttribute* a = FindAttribute(name);
-		if (!a) {
-			return XML_NO_ATTRIBUTE;
-		}
-		return a->QueryInt64Value(value);
-	}
-
-	/// See QueryIntAttribute()
-    XMLError QueryBoolAttribute( const char* name, bool* value ) const				{
-        const XMLAttribute* a = FindAttribute( name );
-        if ( !a ) {
-            return XML_NO_ATTRIBUTE;
-        }
-        return a->QueryBoolValue( value );
-    }
-    /// See QueryIntAttribute()
-    XMLError QueryDoubleAttribute( const char* name, double* value ) const			{
-        const XMLAttribute* a = FindAttribute( name );
-        if ( !a ) {
-            return XML_NO_ATTRIBUTE;
-        }
-        return a->QueryDoubleValue( value );
-    }
-    /// See QueryIntAttribute()
-    XMLError QueryFloatAttribute( const char* name, float* value ) const			{
-        const XMLAttribute* a = FindAttribute( name );
-        if ( !a ) {
-            return XML_NO_ATTRIBUTE;
-        }
-        return a->QueryFloatValue( value );
-    }
-
-	
-    /** Given an attribute name, QueryAttribute() returns
-    	XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
-    	can't be performed, or XML_NO_ATTRIBUTE if the attribute
-    	doesn't exist. It is overloaded for the primitive types,
-		and is a generally more convenient replacement of
-		QueryIntAttribute() and related functions.
-		
-		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;
-    	QueryAttribute( "foo", &value );		// if "foo" isn't found, value will still be 10
-    	@endverbatim
-    */
-	int QueryAttribute( const char* name, int* value ) const {
-		return QueryIntAttribute( name, value );
-	}
-
-	int QueryAttribute( const char* name, unsigned int* value ) const {
-		return QueryUnsignedAttribute( name, value );
-	}
-
-	int QueryAttribute(const char* name, int64_t* value) const {
-		return QueryInt64Attribute(name, value);
-	}
-
-	int QueryAttribute( const char* name, bool* value ) const {
-		return QueryBoolAttribute( name, value );
-	}
-
-	int QueryAttribute( const char* name, double* value ) const {
-		return QueryDoubleAttribute( name, value );
-	}
-
-	int QueryAttribute( const char* name, float* value ) const {
-		return QueryFloatAttribute( name, 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, int64_t 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 );
-    }
-    /// Sets the named attribute to value.
-    void SetAttribute( const char* name, float 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 XMLText child
-    	and accessing it directly.
-
-    	If the first child of 'this' is a XMLText, 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 function for easy access to the text inside an element. Although easy
-    	and concise, SetText() is limited compared to creating an XMLText child
-    	and mutating it directly.
-
-    	If the first child of 'this' is a XMLText, SetText() sets its value to
-		the given string, otherwise it will create a first child that is an XMLText.
-
-    	This is a convenient method for setting the text of simple contained text:
-    	@verbatim
-    	<foo>This is text</foo>
-    		fooElement->SetText( "Hullaballoo!" );
-     	<foo>Hullaballoo!</foo>
-		@endverbatim
-
-    	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 it will not change "This is text", but rather prefix it with a text element:
-    	@verbatim
-    		<foo>Hullaballoo!<b>This is text</b></foo>
-    	@endverbatim
-		
-		For this XML:
-    	@verbatim
-    		<foo />
-    	@endverbatim
-    	SetText() will generate
-    	@verbatim
-    		<foo>Hullaballoo!</foo>
-    	@endverbatim
-    */
-	void SetText( const char* inText );
-    /// Convenience method for setting text inside an element. See SetText() for important limitations.
-    void SetText( int value );
-    /// Convenience method for setting text inside an element. See SetText() for important limitations.
-    void SetText( unsigned value );  
-	/// Convenience method for setting text inside an element. See SetText() for important limitations.
-	void SetText(int64_t value);
-	/// Convenience method for setting text inside an element. See SetText() for important limitations.
-    void SetText( bool value );  
-    /// Convenience method for setting text inside an element. See SetText() for important limitations.
-    void SetText( double value );  
-    /// Convenience method for setting text inside an element. See SetText() for important limitations.
-    void SetText( float value );  
-
-    /**
-    	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.
-
-    */
-    XMLError QueryIntText( int* ival ) const;
-    /// See QueryIntText()
-    XMLError QueryUnsignedText( unsigned* uval ) const;
-	/// See QueryIntText()
-	XMLError QueryInt64Text(int64_t* uval) const;
-	/// See QueryIntText()
-    XMLError QueryBoolText( bool* bval ) const;
-    /// See QueryIntText()
-    XMLError QueryDoubleText( double* dval ) const;
-    /// See QueryIntText()
-    XMLError QueryFloatText( float* fval ) const;
-
-	int IntText(int defaultValue = 0) const;
-
-	/// See QueryIntText()
-	unsigned UnsignedText(unsigned defaultValue = 0) const;
-	/// See QueryIntText()
-	int64_t Int64Text(int64_t defaultValue = 0) const;
-	/// See QueryIntText()
-	bool BoolText(bool defaultValue = false) const;
-	/// See QueryIntText()
-	double DoubleText(double defaultValue = 0) const;
-	/// See QueryIntText()
-	float FloatText(float defaultValue = 0) const;
-
-    // internal:
-    enum ElementClosingType {
-        OPEN,		// <foo>
-        CLOSED,		// <foo/>
-        CLOSING		// </foo>
-    };
-    ElementClosingType ClosingType() const {
-        return _closingType;
-    }
-    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
-    virtual bool ShallowEqual( const XMLNode* compare ) const;
-
-protected:
-    char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
-
-private:
-    XMLElement( XMLDocument* doc );
-    virtual ~XMLElement();
-    XMLElement( const XMLElement& );	// not supported
-    void operator=( const XMLElement& );	// not supported
-
-    XMLAttribute* FindAttribute( const char* name ) {
-        return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
-    }
-    XMLAttribute* FindOrCreateAttribute( const char* name );
-    //void LinkAttribute( XMLAttribute* attrib );
-    char* ParseAttributes( char* p, int* curLineNumPtr );
-    static void DeleteAttribute( XMLAttribute* attribute );
-    XMLAttribute* CreateAttribute();
-
-    enum { BUF_SIZE = 200 };
-    ElementClosingType _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;
-};
-
-
-enum Whitespace {
-    PRESERVE_WHITESPACE,
-    COLLAPSE_WHITESPACE
-};
-
-
-/** 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 TINYXML2_LIB XMLDocument : public XMLNode
-{
-    friend class XMLElement;
-public:
-    /// constructor
-    XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
-    ~XMLDocument();
-
-    virtual XMLDocument* ToDocument()				{
-        TIXMLASSERT( this == _document );
-        return this;
-    }
-    virtual const XMLDocument* ToDocument() const	{
-        TIXMLASSERT( this == _document );
-        return this;
-    }
-
-    /**
-    	Parse an XML file from a character string.
-    	Returns XML_SUCCESS (0) on success, or
-    	an errorID.
-
-    	You may optionally pass in the 'nBytes', which is
-    	the number of bytes which will be parsed. If not
-    	specified, TinyXML-2 will assume 'xml' points to a
-    	null terminated string.
-    */
-    XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
-
-    /**
-    	Load an XML file from disk.
-    	Returns XML_SUCCESS (0) on success, or
-    	an errorID.
-    */
-    XMLError LoadFile( const char* filename );
-
-    /**
-    	Load an XML file from disk. You are responsible
-    	for providing and closing the FILE*. 
-     
-        NOTE: The file should be opened as binary ("rb")
-        not text in order for TinyXML-2 to correctly
-        do newline normalization.
-
-    	Returns XML_SUCCESS (0) on success, or
-    	an errorID.
-    */
-    XMLError LoadFile( FILE* );
-
-    /**
-    	Save the XML file to disk.
-    	Returns XML_SUCCESS (0) on success, or
-    	an errorID.
-    */
-    XMLError SaveFile( const char* filename, bool compact = false );
-
-    /**
-    	Save the XML file to disk. You are responsible
-    	for providing and closing the FILE*.
-
-    	Returns XML_SUCCESS (0) on success, or
-    	an errorID.
-    */
-    XMLError SaveFile( FILE* fp, bool compact = false );
-
-    bool ProcessEntities() const		{
-        return _processEntities;
-    }
-    Whitespace WhitespaceMode() const	{
-        return _whitespaceMode;
-    }
-
-    /**
-    	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 ) const;
-    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 );
-
-    void SetError( XMLError error, const char* str1, const char* str2, int lineNum );
-
-    void ClearError() {
-        SetError(XML_SUCCESS, 0, 0, 0);
-    }
-
-    /// Return true if there was an error parsing the document.
-    bool Error() const {
-        return _errorID != XML_SUCCESS;
-    }
-    /// Return the errorID.
-    XMLError  ErrorID() const {
-        return _errorID;
-    }
-	const char* ErrorName() const;
-    static const char* ErrorIDToName(XMLError errorID);
-
-    /// Return a possibly helpful diagnostic location or string.
-	const char* GetErrorStr1() const;
-
-    /// Return a possibly helpful secondary diagnostic location or string.
-	const char* GetErrorStr2() const;
-
-    /// Return the line where the error occured, or zero if unknown.
-    int GetErrorLineNum() const
-    {
-        return _errorLineNum;
-    }
-    /// If there is an error, print it to stdout.
-    void PrintError() const;
-    
-    /// Clear the document, resetting it to the initial state.
-    void Clear();
-
-	/**
-		Copies this document to a target document.
-		The target will be completely cleared before the copy.
-		If you want to copy a sub-tree, see XMLNode::DeepClone().
-
-		NOTE: that the 'target' must be non-null.
-	*/
-	void DeepCopy(XMLDocument* target);
-
-	// internal
-    char* Identify( char* p, XMLNode** node );
-
-	// internal
-	void MarkInUse(XMLNode*);
-
-    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
-
-    bool			_writeBOM;
-    bool			_processEntities;
-    XMLError		_errorID;
-    Whitespace		_whitespaceMode;
-    mutable StrPair	_errorStr1;
-    mutable StrPair	_errorStr2;
-    int             _errorLineNum;
-    char*			_charBuffer;
-    int				_parseCurLineNum;
-	// Memory tracking does add some overhead.
-	// However, the code assumes that you don't
-	// have a bunch of unlinked nodes around.
-	// Therefore it takes less memory to track
-	// in the document vs. a linked list in the XMLNode,
-	// and the performance is the same.
-	DynArray<XMLNode*, 10> _unlinked;
-
-    MemPoolT< sizeof(XMLElement) >	 _elementPool;
-    MemPoolT< sizeof(XMLAttribute) > _attributePool;
-    MemPoolT< sizeof(XMLText) >		 _textPool;
-    MemPoolT< sizeof(XMLComment) >	 _commentPool;
-
-	static const char* _errorNames[XML_ERROR_COUNT];
-
-    void Parse();
-
-    template<class NodeType, int PoolElementSize>
-    NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
-};
-
-template<class NodeType, int PoolElementSize>
-inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
-{
-    TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
-    TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
-    NodeType* returnNode = new (pool.Alloc()) NodeType( this );
-    TIXMLASSERT( returnNode );
-    returnNode->_memPool = &pool;
-
-	_unlinked.Push(returnNode);
-    return returnNode;
-}
-
-/**
-	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-2
-	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.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
-	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 TINYXML2_LIB 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* name = 0 )						{
-        return XMLHandle( _node ? _node->FirstChildElement( name ) : 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* name = 0 )						{
-        return XMLHandle( _node ? _node->LastChildElement( name ) : 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* name = 0 )				{
-        return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 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* name = 0 )					{
-        return XMLHandle( _node ? _node->NextSiblingElement( name ) : 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() : 0 );
-    }
-    /// Safe cast to XMLText. This can return null.
-    XMLText* ToText() 							{
-        return ( _node ? _node->ToText() : 0 );
-    }
-    /// Safe cast to XMLUnknown. This can return null.
-    XMLUnknown* ToUnknown() 					{
-        return ( _node ? _node->ToUnknown() : 0 );
-    }
-    /// Safe cast to XMLDeclaration. This can return null.
-    XMLDeclaration* ToDeclaration() 			{
-        return ( _node ? _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 TINYXML2_LIB 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* name = 0 ) const				{
-        return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
-    }
-    const XMLConstHandle LastChild()	const										{
-        return XMLConstHandle( _node ? _node->LastChild() : 0 );
-    }
-    const XMLConstHandle LastChildElement( const char* name = 0 ) const				{
-        return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
-    }
-    const XMLConstHandle PreviousSibling() const									{
-        return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
-    }
-    const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const		{
-        return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
-    }
-    const XMLConstHandle NextSibling() const										{
-        return XMLConstHandle( _node ? _node->NextSibling() : 0 );
-    }
-    const XMLConstHandle NextSiblingElement( const char* name = 0 ) const			{
-        return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
-    }
-
-
-    const XMLNode* ToNode() const				{
-        return _node;
-    }
-    const XMLElement* ToElement() const			{
-        return ( _node ? _node->ToElement() : 0 );
-    }
-    const XMLText* ToText() const				{
-        return ( _node ? _node->ToText() : 0 );
-    }
-    const XMLUnknown* ToUnknown() const			{
-        return ( _node ? _node->ToUnknown() : 0 );
-    }
-    const XMLDeclaration* ToDeclaration() const	{
-        return ( _node ? _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 TINYXML2_LIB 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, int depth = 0 );
-    virtual ~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, bool compactMode=false );
-    /// 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, int64_t value);
-	void PushAttribute( const char* name, bool value );
-    void PushAttribute( const char* name, double value );
-    /// If streaming, close the Element.
-    virtual void CloseElement( bool compactMode=false );
-
-    /// 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 an unsigned.
-	void PushText(int64_t 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();
-    }
-    /**
-    	If in print to memory mode, reset the buffer to the
-    	beginning.
-    */
-    void ClearBuffer() {
-        _buffer.Clear();
-        _buffer.Push(0);
-		_firstElement = true;
-    }
-
-protected:
-	virtual bool CompactMode( const XMLElement& )	{ return _compactMode; }
-
-	/** Prints out the space before an element. You may override to change
-	    the space and tabs used. A PrintSpace() override should call Print().
-	*/
-    virtual void PrintSpace( int depth );
-    void Print( const char* format, ... );
-
-    void SealElementIfJustOpened();
-    bool _elementJustOpened;
-    DynArray< const char*, 10 > _stack;
-
-private:
-    void PrintString( const char*, bool restrictedEntitySet );	// prints out, after detecting entities.
-
-    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< char, 20 > _buffer;
-};
-
-
-}	// tinyxml2
-
-#if defined(_MSC_VER)
-#   pragma warning(pop)
-#endif
-
-#endif // TINYXML2_INCLUDED
diff --git a/deps/yaracpp/CMakeLists.txt b/deps/yaracpp/CMakeLists.txt
index 6e4631e3..5ef146d4 100644
--- a/deps/yaracpp/CMakeLists.txt
+++ b/deps/yaracpp/CMakeLists.txt
@@ -1,11 +1,24 @@
 include(ExternalProject)
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 ExternalProject_Add(yaracpp-project
-	URL https://github.com/avast-tl/yaracpp/archive/a284ab17ab04d91f1725f579a8670a12ef1afd76.zip
-	URL_HASH SHA256=ff5e5996e90a56f2752c69ac7a12009075f7f355da5bff37e562239ae9749e44
+	URL https://github.com/avast-tl/yaracpp/archive/v1.0.1.zip
+	URL_HASH SHA256=2252ba7cfd9b190d3e260a741bbd2abc0fbd7c0422eb13d878278a89016c4fda
+	DOWNLOAD_NAME yaracpp.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
 	# Disable the update step.
 	UPDATE_COMMAND ""
 	# Disable the install step.
@@ -25,16 +38,32 @@ set(YARA_LIBRARY_NAME "libyara")
 if(MSVC)
 	if(CMAKE_SIZEOF_VOID_P EQUAL 8)
 		set(YARA_LIBRARY_NAME "${YARA_LIBRARY_NAME}64")
+		set(YARAC_NAME "yarac64.exe" CACHE STRING "Yarac binary name" FORCE)
 	else()
 		set(YARA_LIBRARY_NAME "${YARA_LIBRARY_NAME}32")
+		set(YARAC_NAME "yarac32.exe" CACHE STRING "Yarac binary name" FORCE)
 	endif()
 
 	set(YARA_WIN_DIR       ${YARA_DIR}/windows/vs2015)
 	set(YARA_LIBRARY_DIR   ${YARA_WIN_DIR}/libyara/$<CONFIGURATION>)
+	set(YARAC_PATH         ${YARA_WIN_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/${YARAC_NAME})
 else()
 	set(YARA_LIBRARY_DIR   ${YARA_DIR}/libyara/.libs)
+	set(YARAC_PATH         ${YARA_DIR}/yarac)
 endif()
 
+# Compile YARA rules for tools detection.
+set(YARA_COMPILE_SH ${CMAKE_SOURCE_DIR}/support/yara_patterns/tools/compile-yara.sh)
+install(CODE "
+	execute_process(
+		COMMAND sh \"${YARA_COMPILE_SH}\" \"${YARAC_PATH}\" \"${CMAKE_SOURCE_DIR}\" \"${CMAKE_INSTALL_PREFIX}\"
+		RESULT_VARIABLE COMPILE_YARA_RES
+	)
+	if(COMPILE_YARA_RES)
+		message(FATAL_ERROR \"YARA tool signatures compilation FAILED\")
+	endif()
+")
+
 # Add libraries.
 add_library(yaracpp INTERFACE)
 add_dependencies(yaracpp yaracpp-project)
diff --git a/deps/yaramod/CMakeLists.txt b/deps/yaramod/CMakeLists.txt
index d4783b8a..cfbb58e0 100644
--- a/deps/yaramod/CMakeLists.txt
+++ b/deps/yaramod/CMakeLists.txt
@@ -4,12 +4,25 @@ find_package(BISON REQUIRED)
 
 include(ExternalProject)
 
+if(CMAKE_C_COMPILER)
+	set(CMAKE_C_COMPILER_OPTION "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+endif()
+if(CMAKE_CXX_COMPILER)
+	set(CMAKE_CXX_COMPILER_OPTION "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+endif()
+
 ExternalProject_Add(yaramod-project
-	URL https://github.com/avast-tl/yaramod/archive/122610928203f4606276e1cb2552f04f6dd33c32.zip
-	URL_HASH SHA256=7fac768ccc8699fc44c1bac1e9ebea8ab57654f34a53ff772b025e50fa66c760
+	URL https://github.com/avast-tl/yaramod/archive/v1.0.1.zip
+	URL_HASH SHA256=20793f99bd1a22e9b743400653d54790a48457ef0ae1cf8f089a1bf3bf38f339
+	DOWNLOAD_NAME yaramod.zip
 	CMAKE_ARGS
 		# This does not work on MSVC, but may be useful on Linux.
 		-DCMAKE_BUILD_TYPE=Release
+		# Force the use of the same compiler as used to build the top-level
+		# project. Otherwise, the external project may pick up a different
+		# compiler, which may result in link errors.
+		"${CMAKE_C_COMPILER_OPTION}"
+		"${CMAKE_CXX_COMPILER_OPTION}"
 	# Disable the update step.
 	UPDATE_COMMAND ""
 	# Disable the install step.
diff --git a/include/retdec/utils/os.h b/include/retdec/utils/os.h
index 78a5b4eb..9c5f73cb 100644
--- a/include/retdec/utils/os.h
+++ b/include/retdec/utils/os.h
@@ -8,11 +8,11 @@
 #define RETDEC_UTILS_OS_H
 
 // Obtain the used operating system. Currently, we only distinguish between
-// Windows and Linux.
+// Windows and UNIX.
 #if defined(__WIN) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
 	#define OS_WINDOWS
 #else
-	#define OS_LINUX
+	#define OS_UNIX
 #endif
 
 #endif
diff --git a/scripts/retdec-archive-decompiler.sh b/scripts/retdec-archive-decompiler.sh
index 66124d1b..c0fd9f31 100644
--- a/scripts/retdec-archive-decompiler.sh
+++ b/scripts/retdec-archive-decompiler.sh
@@ -8,10 +8,10 @@
 #  - the `timeout` command
 #
 
-SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 
 if [ -z "$DECOMPILER_UTILS" ]; then
-	DECOMPILER_UTILS="$SCRIPTPATH/retdec-utils.sh"
+	DECOMPILER_UTILS="$SCRIPT_DIR/retdec-utils.sh"
 fi
 
 . "$DECOMPILER_UTILS"
diff --git a/scripts/retdec-config.sh b/scripts/retdec-config.sh
index e77c217d..a8a9f841 100644
--- a/scripts/retdec-config.sh
+++ b/scripts/retdec-config.sh
@@ -3,14 +3,14 @@
 # Decompiler's configuration. This file should be included in every decompilation script.
 #
 
-SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 
 ##
 ## Paths (everything has to be without the ending slash '/').
 ##
 
 # Paths relative from script path.
-INSTALL_BIN_DIR="$SCRIPTPATH"
+INSTALL_BIN_DIR="$SCRIPT_DIR"
 UNIT_TESTS_DIR="$INSTALL_BIN_DIR"
 INSTALL_SHARE_DIR="$INSTALL_BIN_DIR/../share/retdec"
 INSTALL_SUPPORT_DIR="$INSTALL_SHARE_DIR/support"
diff --git a/scripts/retdec-decompiler.sh b/scripts/retdec-decompiler.sh
index 4ac8a3c8..1dc7fcb0 100644
--- a/scripts/retdec-decompiler.sh
+++ b/scripts/retdec-decompiler.sh
@@ -3,10 +3,10 @@
 # The script decompiles the given file into the selected target high-level language.
 #
 
-SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 
 if [ -z "$DECOMPILER_UTILS" ]; then
-	DECOMPILER_UTILS="$SCRIPTPATH/retdec-utils.sh"
+	DECOMPILER_UTILS="$SCRIPT_DIR/retdec-utils.sh"
 fi
 
 . "$DECOMPILER_UTILS"
@@ -162,10 +162,10 @@ check_arguments()
 	fi
 
 	# Convert to absolute paths.
-	IN="$(readlink -f "$IN")"
-	OUT="$(readlink -f "$OUT")"
+	IN="$(get_realpath "$IN")"
+	OUT="$(get_realpath "$OUT")"
 	if [ -e "$PDB_FILE" ]; then
-		PDB_FILE="$(readlink -f "$PDB_FILE")"
+		PDB_FILE="$(get_realpath "$PDB_FILE")"
 	fi
 
 	# Check that selected ranges are valid.
@@ -245,8 +245,7 @@ PARSED_OPTIONS=$(getopt -o "$GETOPT_SHORTOPT" -l "$GETOPT_LONGOPT" -n "$SCRIPT_N
 
 eval set -- "$PARSED_OPTIONS"
 
-while true ;
-do
+while true; do
 	case "$1" in
 	-a|--arch)						# Target architecture.
 		[ "$ARCH" ] && print_error_and_die "Duplicate option: -a|--arch"
@@ -497,10 +496,7 @@ done
 check_arguments
 
 if [ "$MODE" = "raw" ]; then
-
-	##
-	## Default values and initialization.
-	##
+	# Default values and initialization.
 	OUT_RAW_EXECUTABLE="$IN"
 
 	# Entry point for THUMB must be odd.
@@ -513,7 +509,6 @@ fi
 
 # Check for archives.
 if [ "$MODE" = "bin" ]; then
-
 	# Check for archives packed in Mach-O Universal Binaries.
 	echo "##### Checking if file is a Mach-O Universal static library..."
 	echo "RUN: $EXTRACT --list $IN"
@@ -937,9 +932,7 @@ if [ "$BACKEND_EMIT_CFG" ]; then
 	[ "$BACKEND_CFG_TEST" ] && LLVMIR2HLL_PARAMS+=(--backend-cfg-test)
 fi
 
-##
-## Decompile the optimized IR code.
-##
+# Decompile the optimized IR code.
 echo ""
 echo "##### Decompiling $OUT_BACKEND_BC into $OUT..."
 echo "RUN: $LLVMIR2HLL ${LLVMIR2HLL_PARAMS[@]}"
@@ -957,9 +950,8 @@ check_whether_decompilation_should_be_forcefully_stopped "llvmir2hll"
 GRAPH_FORMAT=${GRAPH_FORMAT:=png}
 BACKEND_CG_CONVERSION=${BACKEND_CG_CONVERSION:=auto}
 BACKEND_CFG_CONVERSION=${BACKEND_CFG_CONVERSION:=auto}
-##
-## Convert .dot graphs to desired format.
-##
+
+# Convert .dot graphs to desired format.
 if [[ ( "$BACKEND_EMIT_CG" && "$BACKEND_CG_CONVERSION" = "auto" ) ||
 		( "$BACKEND_EMIT_CFG" && "$BACKEND_CFG_CONVERSION" = "auto" ) ]]; then
 	echo ""
@@ -982,9 +974,7 @@ fi
 sed -i 's/[ \t]*$//' "$OUT"
 sed -i '$ { /^$/ d}' "$OUT"
 
-##
-## Colorize output file.
-##
+# Colorize output file.
 if [ "$COLOR_IDA" ]; then
 	"$IDA_COLORIZER" "$OUT" "$CONFIG"
 fi
diff --git a/scripts/retdec-fileinfo.sh b/scripts/retdec-fileinfo.sh
index b5de6226..7330d51d 100644
--- a/scripts/retdec-fileinfo.sh
+++ b/scripts/retdec-fileinfo.sh
@@ -6,10 +6,10 @@
 #  - is able to analyze archives (.a/.lib files).
 #
 
-SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 
 if [ -z "$DECOMPILER_UTILS" ]; then
-	DECOMPILER_UTILS="$SCRIPTPATH/retdec-utils.sh"
+	DECOMPILER_UTILS="$SCRIPT_DIR/retdec-utils.sh"
 fi
 
 . "$DECOMPILER_UTILS"
diff --git a/scripts/retdec-signature-from-library-creator.sh b/scripts/retdec-signature-from-library-creator.sh
index fa2a1ee5..82d3a279 100644
--- a/scripts/retdec-signature-from-library-creator.sh
+++ b/scripts/retdec-signature-from-library-creator.sh
@@ -1,9 +1,9 @@
 #!/bin/bash
 
-SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 
 if [ -z "$DECOMPILER_UTILS" ]; then
-	DECOMPILER_UTILS="$SCRIPTPATH/retdec-utils.sh"
+	DECOMPILER_UTILS="$SCRIPT_DIR/retdec-utils.sh"
 fi
 
 . "$DECOMPILER_UTILS"
@@ -97,7 +97,7 @@ if [ -z "$OUT_PATH" ]; then
 	die_with_error_and_cleanup "option -o|--output is compulsory"
 else
 	FILE_PATH="$OUT_PATH"
-	DIR="$(dirname "$(readlink -f "$FILE_PATH")")"
+	DIR="$(dirname "$(get_realpath "$FILE_PATH")")"
 	DIR_PATH=$(mktemp -d "$DIR/XXXXXXXXX")
 fi
 
diff --git a/scripts/retdec-tests-runner.sh b/scripts/retdec-tests-runner.sh
index 7e643c85..eecc40b2 100644
--- a/scripts/retdec-tests-runner.sh
+++ b/scripts/retdec-tests-runner.sh
@@ -3,13 +3,20 @@
 # Runs all the installed unit tests.
 #
 
-SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 
 if [ -z "$DECOMPILER_CONFIG" ]; then
-	DECOMPILER_CONFIG="$SCRIPTPATH/retdec-config.sh"
+	DECOMPILER_CONFIG="$SCRIPT_DIR/retdec-config.sh"
 fi
 . "$DECOMPILER_CONFIG"
 
+#
+# First argument can be verbose.
+#
+if [ "$1" = "-v" ] || [ "$1" = "--verbose" ]; then
+	VERBOSE=1
+fi
+
 #
 # Emits a colored version of the given message to the standard output (without
 # a new line).
@@ -58,8 +65,12 @@ run_unit_tests_in_dir() {
 		unit_test_name="$(sed 's/^.*\/bin\///' <<< "$unit_test")"
 		echo_colored "$unit_test_name" "yellow"
 		echo ""
-		$unit_test --gtest_color=yes | grep -v "RUN\|OK\|----------\|==========" |\
-			grep -v "^$" | grep -v "Running main() from gmock_main.cc"
+		if [ "$VERBOSE" ]; then
+			$unit_test --gtest_color=yes
+		else
+			$unit_test --gtest_color=yes | grep -v "RUN\|OK\|----------\|==========" |\
+				grep -v "^$" | grep -v "Running main() from gmock_main.cc"
+		fi
 		RC=${PIPESTATUS[0]}
 		if [ "$RC" != "0" ]; then
 			TESTS_FAILED="1"
diff --git a/scripts/retdec-unpacker.sh b/scripts/retdec-unpacker.sh
index d7d3da48..3abd0e0d 100644
--- a/scripts/retdec-unpacker.sh
+++ b/scripts/retdec-unpacker.sh
@@ -26,10 +26,10 @@ RET_UNPACKER_FAILED=4
 # 10 other errors
 #RET_OTHER_ERRORS=10
 
-SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 
 if [ -z "$DECOMPILER_UTILS" ]; then
-	DECOMPILER_UTILS="$SCRIPTPATH/retdec-utils.sh"
+	DECOMPILER_UTILS="$SCRIPT_DIR/retdec-utils.sh"
 fi
 
 . "$DECOMPILER_UTILS"
@@ -64,8 +64,8 @@ check_arguments()
 	OUT=${OUT:="$IN"-unpacked}
 
 	# Convert to absolute paths.
-	IN="$(readlink -f "$IN")"
-	OUT="$(readlink -f "$OUT")"
+	IN="$(get_realpath "$IN")"
+	OUT="$(get_realpath "$OUT")"
 }
 
 #
diff --git a/scripts/retdec-utils.sh b/scripts/retdec-utils.sh
index a354ad89..e86054e4 100644
--- a/scripts/retdec-utils.sh
+++ b/scripts/retdec-utils.sh
@@ -3,14 +3,34 @@
 # Compilation and decompilation utility functions.
 #
 
-SCRIPTPATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 
 if [ -z "$DECOMPILER_CONFIG" ]; then
-	DECOMPILER_CONFIG="$SCRIPTPATH/retdec-config.sh"
+	DECOMPILER_CONFIG="$SCRIPT_DIR/retdec-config.sh"
 fi
 
 . "$DECOMPILER_CONFIG"
 
+#
+# Prints the real, physical location of a directory or file, relative or
+# absolute.
+# 1 argument is needed
+#
+get_realpath()
+{
+	local input_path="$1"
+	# Use cygpath.exe on cygwin, due to cygwins virtual folder mountpoints
+	# (i.e., "/cygdrive/c/foo/bar" becomes "c:/foo/bar").
+	# cygpath args:
+	#   -m -- mixed mode, that is, forward slashes, instead of backward slashes
+	#   -a -- absolute path (regardless if input is relative or not)
+	if [[ "$(uname -s)" == *CYGWIN* ]]; then
+		cygpath -ma "$input_path"
+	else
+		readlink -f "$input_path"
+	fi
+}
+
 #
 # Print error message to stderr and die.
 # 1 argument is needed
diff --git a/scripts/type_extractor/gen_cstdlib_and_linux_jsons.sh b/scripts/type_extractor/gen_cstdlib_and_linux_jsons.sh
index 53c0807d..e68925e0 100755
--- a/scripts/type_extractor/gen_cstdlib_and_linux_jsons.sh
+++ b/scripts/type_extractor/gen_cstdlib_and_linux_jsons.sh
@@ -70,7 +70,7 @@ FILES_FILTER=${FILES_FILTER:${#SEP}}
 #
 # Paths.
 #
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd -P)"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 SCRIPT_NAME="$(basename "$SCRIPT_NAME")"
 EXTRACTOR="$SCRIPT_DIR/extract_types.py"
 MERGER="$SCRIPT_DIR/merge_jsons.py"
diff --git a/scripts/type_extractor/gen_windows_and_windrivers_jsons.sh b/scripts/type_extractor/gen_windows_and_windrivers_jsons.sh
index 136c3682..efcffdbb 100755
--- a/scripts/type_extractor/gen_windows_and_windrivers_jsons.sh
+++ b/scripts/type_extractor/gen_windows_and_windrivers_jsons.sh
@@ -6,7 +6,7 @@
 #
 # Paths.
 #
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd -P)"
+SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
 SCRIPT_NAME="$(basename "$SCRIPT_NAME")"
 EXTRACTOR="$SCRIPT_DIR/extract_types.py"
 MERGER="$SCRIPT_DIR/merge_jsons.py"
diff --git a/src/ar-extractor/archive_wrapper.cpp b/src/ar-extractor/archive_wrapper.cpp
index e69bb2a4..93487bae 100644
--- a/src/ar-extractor/archive_wrapper.cpp
+++ b/src/ar-extractor/archive_wrapper.cpp
@@ -228,7 +228,7 @@ bool ArchiveWrapper::getJsonList(
 			Value object(kObjectType);
 			object.AddMember("name", Value(outName.c_str(), allocator).Move(), allocator);
 			if (numbers) {
-				object.AddMember("index", (uint64_t) counter++, allocator);
+				object.AddMember("index", static_cast<uint64_t>(counter++), allocator);
 			}
 			objects.PushBack(object, allocator);
 		}
diff --git a/src/bin2llvmirtool/bin2llvmir.cpp b/src/bin2llvmirtool/bin2llvmir.cpp
index c5625dbb..45bbb50c 100644
--- a/src/bin2llvmirtool/bin2llvmir.cpp
+++ b/src/bin2llvmirtool/bin2llvmir.cpp
@@ -35,7 +35,6 @@
 #include <llvm/IRReader/IRReader.h>
 #include <llvm/InitializePasses.h>
 #include <llvm/LinkAllIR.h>
-#include <llvm/LinkAllPasses.h>
 #include <llvm/MC/SubtargetFeature.h>
 #include <llvm/Support/Debug.h>
 #include <llvm/Support/FileSystem.h>
@@ -272,34 +271,15 @@ static inline void addPassWithoutVerification(
  */
 void initializeLlvmPasses()
 {
-	InitializeAllTargets();
-	InitializeAllTargetMCs();
-	InitializeAllAsmPrinters();
 	// Initialize passes
 	PassRegistry &Registry = *PassRegistry::getPassRegistry();
 	initializeCore(Registry);
 	initializeScalarOpts(Registry);
-	initializeObjCARCOpts(Registry);
-	initializeVectorization(Registry);
 	initializeIPO(Registry);
 	initializeAnalysis(Registry);
 	initializeTransformUtils(Registry);
 	initializeInstCombine(Registry);
-	initializeInstrumentation(Registry);
 	initializeTarget(Registry);
-	// For codegen passes, only passes that do IR to IR transformation are
-	// supported.
-	initializeCodeGenPreparePass(Registry);
-	initializeAtomicExpandPass(Registry);
-	initializeRewriteSymbolsPass(Registry);
-	initializeWinEHPreparePass(Registry);
-	initializeDwarfEHPreparePass(Registry);
-	initializeSafeStackPass(Registry);
-	initializeSjLjEHPreparePass(Registry);
-	initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
-	initializeGlobalMergePass(Registry);
-	initializeInterleavedAccessPass(Registry);
-	initializeUnreachableBlockElimLegacyPassPass(Registry);
 }
 
 /**
diff --git a/src/llvmir-emul/llvmir_emul.cpp b/src/llvmir-emul/llvmir_emul.cpp
index b6bd1914..78934376 100644
--- a/src/llvmir-emul/llvmir_emul.cpp
+++ b/src/llvmir-emul/llvmir_emul.cpp
@@ -6,18 +6,6 @@
 
 #include <iostream>
 
-#include <llvm/ADT/StringExtras.h>
-#include <llvm/ADT/Triple.h>
-#include <llvm/Bitcode/ReaderWriter.h>
-#include <llvm/CodeGen/LinkAllCodegenComponents.h>
-#include <llvm/ExecutionEngine/GenericValue.h>
-#include <llvm/ExecutionEngine/Interpreter.h>
-#include <llvm/ExecutionEngine/JITEventListener.h>
-#include <llvm/ExecutionEngine/MCJIT.h>
-#include <llvm/ExecutionEngine/ObjectCache.h>
-#include <llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h>
-#include <llvm/ExecutionEngine/OrcMCJITReplacement.h>
-#include <llvm/ExecutionEngine/SectionMemoryManager.h>
 #include <llvm/IR/CallSite.h>
 #include <llvm/IR/GetElementPtrTypeIterator.h>
 #include <llvm/IR/IRBuilder.h>
@@ -26,9 +14,6 @@
 #include <llvm/IR/Module.h>
 #include <llvm/IR/Type.h>
 #include <llvm/IR/TypeBuilder.h>
-#include <llvm/IRReader/IRReader.h>
-#include <llvm/Object/Archive.h>
-#include <llvm/Object/ObjectFile.h>
 #include <llvm/Support/CommandLine.h>
 #include <llvm/Support/Debug.h>
 #include <llvm/Support/DynamicLibrary.h>
@@ -46,7 +31,6 @@
 #include <llvm/Support/SourceMgr.h>
 #include <llvm/Support/TargetSelect.h>
 #include <llvm/Support/raw_ostream.h>
-#include <llvm/Transforms/Instrumentation.h>
 
 #include "retdec/llvmir-emul/llvmir_emul.h"
 
@@ -3071,10 +3055,9 @@ void LlvmIrEmulator::visitCallInst(llvm::CallInst& I)
 	if (cf && cf->isDeclaration() && cf->isIntrinsic() &&
 			cf->getIntrinsicID() != Intrinsic::fabs) // can not lower fabs
 	{
-		auto iId = cf->getIntrinsicID();
-		assert(iId != Intrinsic::vastart
-				&& iId != Intrinsic::vaend
-				&& iId != Intrinsic::vacopy);
+		assert(cf->getIntrinsicID() != Intrinsic::vastart
+				&& cf->getIntrinsicID() != Intrinsic::vaend
+				&& cf->getIntrinsicID() != Intrinsic::vacopy);
 
 		BasicBlock::iterator me(&I);
 		BasicBlock *Parent = I.getParent();
diff --git a/src/unpacker/dynamic_buffer.cpp b/src/unpacker/dynamic_buffer.cpp
index 4bc96d75..ff54be27 100644
--- a/src/unpacker/dynamic_buffer.cpp
+++ b/src/unpacker/dynamic_buffer.cpp
@@ -82,7 +82,7 @@ DynamicBuffer::~DynamicBuffer()
  *
  * @param rhs Right hand side of the operator.
  *
- * @return The new DynamicBuffer opbject.
+ * @return The new DynamicBuffer object.
  */
 DynamicBuffer& DynamicBuffer::operator =(DynamicBuffer rhs)
 {
diff --git a/src/utils/filesystem_path.cpp b/src/utils/filesystem_path.cpp
index f4988f8e..937f61fe 100644
--- a/src/utils/filesystem_path.cpp
+++ b/src/utils/filesystem_path.cpp
@@ -5,9 +5,11 @@
  */
 
 #include <string>
+#include <iterator>
 
 #include "retdec/utils/filesystem_path.h"
 #include "retdec/utils/os.h"
+#include "retdec/utils/scope_exit.h"
 #include "retdec/utils/string.h"
 #include "retdec/utils/value.h"
 
@@ -27,27 +29,14 @@ namespace utils {
 class FilesystemPathImpl
 {
 public:
-	FilesystemPathImpl(const std::string& path)
-		: _path(), _parentPath(), _subpaths(), _exists(), _isFile(), _isDirectory(), _isAbsolute()
+	FilesystemPathImpl(const std::string& path) : _path()
 	{
 		changePath(path);
 	}
 
-	FilesystemPathImpl(const FilesystemPathImpl& rhs)
-		: _path(rhs._path), _parentPath(rhs._parentPath), _subpaths(rhs._subpaths), _exists(rhs._exists),
-		_isFile(rhs._isFile), _isDirectory(rhs._isDirectory), _isAbsolute(rhs._isAbsolute) {}
+	FilesystemPathImpl(const FilesystemPathImpl& rhs) : _path(rhs._path) {}
 	virtual ~FilesystemPathImpl() = default;
 
-	void reset()
-	{
-		_parentPath = {};
-		_subpaths = {};
-		_exists = {};
-		_isFile = {};
-		_isDirectory = {};
-		_isAbsolute = {};
-	}
-
 	/**
 	 * Returns the path.
 	 *
@@ -67,7 +56,6 @@ public:
 	 */
 	void changePath(std::string path)
 	{
-		reset();
 		std::replace(path.begin(), path.end(), '/', pathSeparator);
 		_path = endsWith(path, pathSeparator) ? path.substr(0, path.length() - 1) : path;
 	}
@@ -84,9 +72,6 @@ public:
 
 protected:
 	std::string _path;
-	Maybe<std::string> _absolutePath, _parentPath;
-	Maybe<std::vector<std::string>> _subpaths;
-	Maybe<bool> _exists, _isFile, _isDirectory, _isAbsolute;
 };
 
 #ifdef OS_WINDOWS
@@ -100,42 +85,27 @@ public:
 
 	virtual std::string getAbsolutePath() override
 	{
-		if (_absolutePath.isDefined())
-			return _absolutePath;
-
 		char absolutePath[MAX_PATH] = { '\0' };
 		if (GetFullPathName(_path.c_str(), MAX_PATH, absolutePath, nullptr) == 0)
 			return {};
 
-		_absolutePath = std::string(absolutePath);
-		return _absolutePath;
+		return absolutePath;
 	}
 
 	virtual std::string getParentPath() override
 	{
-		if (_parentPath.isDefined())
-			return _parentPath;
-
 		// PathRemoveFileSpec() supports only MAX_PATH long paths and modify its parameter
 		char parentPathStr[MAX_PATH] = { '\0' };
 		strncpy(parentPathStr, _path.c_str(), MAX_PATH - 1);
 
 		PathRemoveFileSpec(parentPathStr);
-
-		_parentPath = std::string(parentPathStr);
-		return _parentPath;
+		return parentPathStr;
 	}
 
 	virtual bool subpathsInDirectory(std::vector<std::string>& subpaths) override
 	{
 		using namespace std::string_literals;
 
-		if (_subpaths.isDefined())
-		{
-			subpaths = _subpaths.getValue();
-			return true;
-		}
-
 		WIN32_FIND_DATA ffd;
 
 		// We need to add wildcard to examine the content of the directory
@@ -145,10 +115,7 @@ public:
 		subpaths.clear();
 		HANDLE hFnd = FindFirstFile(examineDir.c_str(), &ffd);
 		if (hFnd == reinterpret_cast<HANDLE>(-1))
-		{
-			_subpaths = std::vector<std::string>{};
 			return false;
-		}
 
 		do
 		{
@@ -164,55 +131,31 @@ public:
 			subpaths.emplace_back(newPath);
 		} while (FindNextFile(hFnd, &ffd));
 
-		_subpaths = subpaths;
 		return true;
 	}
 
 	virtual bool exists() override
 	{
-		if (_exists.isDefined())
-			return _exists;
-
-		_exists = PathFileExists(_path.c_str());
-		return _exists;
+		return PathFileExists(_path.c_str());
 	}
 
 	virtual bool isFile() override
 	{
-		if (_isFile.isDefined())
-			return _isFile;
-
-		isDirectory();
-		return _isFile;
+		return !isDirectory();
 	}
 
 	virtual bool isDirectory() override
 	{
-		if (_isDirectory.isDefined())
-			return _isDirectory;
-
 		WIN32_FIND_DATA ffd;
 		if (FindFirstFile(_path.c_str(), &ffd) == reinterpret_cast<HANDLE>(-1))
-		{
-			_exists = false;
-			_isDirectory = false;
-			_isFile = false;
 			return false;
-		}
 
-		_exists = true;
-		_isDirectory = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
-		_isFile = !_isDirectory;
-		return _isDirectory;
+		return ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
 	}
 
 	virtual bool isAbsolute() override
 	{
-		if (_isAbsolute.isDefined())
-			return _isAbsolute;
-
-		_isAbsolute = !PathIsRelative(_path.c_str());
-		return _isAbsolute;
+		return !PathIsRelative(_path.c_str());
 	}
 };
 #else
@@ -226,43 +169,36 @@ public:
 
 	virtual std::string getAbsolutePath() override
 	{
-		if (_absolutePath.isDefined())
-			return _absolutePath;
-
+#ifdef PATH_MAX
 		char absolutePath[PATH_MAX] = { '\0' };
 		if (realpath(_path.c_str(), absolutePath) == nullptr)
 			return {};
+#else
+		char* absolutePathStr = realpath(_path.c_str(), nullptr);
+		SCOPE_EXIT {
+			free(absolutePathStr);
+		};
+		std::string absolutePath = absolutePathStr;
+#endif
 
-		_absolutePath = std::string(absolutePath);
-		return _absolutePath;
+		return absolutePath;
 	}
 
 	virtual std::string getParentPath() override
 	{
-		if (_parentPath.isDefined())
-			return _parentPath;
-
 		// dirname() can modify the path provided in parameter, so we need to make copy
 		char* copyPathStr = new char[_path.length() + 1];
+		SCOPE_EXIT {
+			delete[] copyPathStr;
+		};
 		strcpy(copyPathStr, _path.c_str());
 
 		// get the parent directory by calling dirname()
-		char* parentPathStr = dirname(copyPathStr);
-
-		// copy the parent path into the string, so we can free the memory
-		_parentPath = std::string(parentPathStr);
-		delete[] copyPathStr;
-		return _parentPath;
+		return dirname(copyPathStr);
 	}
 
 	virtual bool subpathsInDirectory(std::vector<std::string>& subpaths) override
 	{
-		if (_subpaths.isDefined())
-		{
-			subpaths = _subpaths.getValue();
-			return true;
-		}
-
 		subpaths.clear();
 		DIR* dir = opendir(_path.c_str());
 		if (dir == nullptr)
@@ -284,46 +220,27 @@ public:
 		}
 		closedir(dir);
 
-		_subpaths = subpaths;
 		return true;
 	}
 
 	virtual bool exists() override
 	{
-		if (_exists.isDefined())
-			return _exists;
-
-		isDirectory();
-		return _exists;
+		struct stat st;
+		return stat(_path.c_str(), &st) != 0;
 	}
 
 	virtual bool isFile() override
 	{
-		if (_isFile.isDefined())
-			return _isFile;
-
-		isDirectory();
-		return _isFile;
+		return !isDirectory();
 	}
 
 	virtual bool isDirectory() override
 	{
-		if (_isDirectory.isDefined())
-			return _isDirectory;
-
 		struct stat st;
 		if (stat(_path.c_str(), &st) != 0)
-		{
-			_exists = false;
-			_isDirectory = false;
-			_isFile = false;
 			return false;
-		}
 
-		_exists = true;
-		_isDirectory = S_ISDIR(st.st_mode);
-		_isFile = S_ISREG(st.st_mode);
-		return _isDirectory;
+		return S_ISDIR(st.st_mode);
 	}
 
 	virtual bool isAbsolute() override
@@ -528,11 +445,10 @@ void FilesystemPath::loadSubpaths() const
 	if (!_impl->subpathsInDirectory(subpaths))
 		return;
 
-	for (const auto& subpath : subpaths)
-	{
-		auto fsSubpath = std::make_unique<FilesystemPath>(subpath);
-		_subpaths.push_back(std::move(fsSubpath));
-	}
+	std::transform(subpaths.begin(), subpaths.end(), std::back_inserter(_subpaths),
+			[](const auto& subpath) {
+				return std::make_unique<FilesystemPath>(subpath);
+			});
 
 	_subpathsLoaded = true;
 }
diff --git a/src/utils/time.cpp b/src/utils/time.cpp
index 7a4ad61a..6cc280f3 100644
--- a/src/utils/time.cpp
+++ b/src/utils/time.cpp
@@ -85,20 +85,17 @@ std::string getCurrentYear() {
 * @brief Returns date in human readable form.
 * @param tm Timestamp for conversion.
 */
-std::string timestampToDate(std::tm *tm)
-{
-	if(!tm) {
+std::string timestampToDate(std::tm *tm) {
+	if (!tm) {
 		return "";
 	}
 	const auto conDate = getDate(tm);
 	const auto conTime = getTime(tm);
 	if (conDate.empty() && conTime.empty()) {
 		return "";
-	}
-	else if (conDate.empty()) {
+	} else if (conDate.empty()) {
 		return conTime;
-	}
-	else if (conTime.empty()) {
+	} else if (conTime.empty()) {
 		return conDate;
 	}
 
diff --git a/support/README b/support/README
new file mode 100644
index 00000000..5a3cf7d1
--- /dev/null
+++ b/support/README
@@ -0,0 +1 @@
+Compilation and installation of YARA rules is done in deps/yaracpp.
diff --git a/support/yara_patterns/tools/compile-yara.sh b/support/yara_patterns/tools/compile-yara.sh
new file mode 100644
index 00000000..72ca0f27
--- /dev/null
+++ b/support/yara_patterns/tools/compile-yara.sh
@@ -0,0 +1,112 @@
+#!/bin/sh
+#
+# Compile and install tool signatures.
+# Usage: compile-yara.sh yarac-path source-path install-path
+#
+
+###############################################################################
+
+# Print error and exit with non-zero value.
+#     $1 - error message.
+printErrorAndDie()
+{
+	if ! [ -z "$1" ]; then
+		echo "Error: $1."
+	fi
+	exit 1
+}
+
+# Compile yara signatures.
+#     $1 - input folder
+#     $2 - output file
+compileFiles()
+{
+	ERR_OUT="$("$CC" -w "$1"/*.yara "$2" 2>&1)"
+	if [ $? -ne 0 ]; then
+		printErrorAndDie "yarac failed during compilation of file $1"
+	fi
+
+	# Check for errors in output - yarac returns 0 when it should not.
+	case "$ERR_OUT" in
+  *error*)
+    printErrorAndDie "yarac failed during compilation of file $1"
+    ;;
+esac
+}
+
+###############################################################################
+
+CC="$1"
+if [ -z "$CC" ]; then
+	printErrorAndDie "missing path to yarac"
+fi
+
+SRC="$2"
+if [ -z "$SRC" ]; then
+	printErrorAndDie "missing path to rules folder"
+fi
+
+OUT="$3"
+if [ -z "$OUT" ]; then
+	printErrorAndDie "missing path to install folder"
+fi
+
+###############################################################################
+
+# Convert from Windows to Unix path on Windows.
+case "$(uname -s)" in
+	*Windows*|*CYGWIN*|*MINGW*|*MSYS*)
+		CC="$(echo "/$CC" | sed -e 's/\\/\//g' -e 's/://')"
+		SRC="$(echo "/$SRC" | sed -e 's/\\/\//g' -e 's/://')"
+		OUT="$(echo "/$OUT" | sed -e 's/\\/\//g' -e 's/://')"
+		;;
+esac
+
+# Directory paths.
+SRC="$SRC/support/yara_patterns/tools"
+OUT="$OUT/share/retdec/support/generic/yara_patterns/tools"
+
+###############################################################################
+
+# Remove old files if present.
+rm -rf "$OUT"
+
+# Prepare directory structure.
+mkdir -p "$OUT/pe"
+mkdir -p "$OUT/elf"
+mkdir -p "$OUT/macho"
+
+###############################################################################
+
+echo "compiling yara signatures..."
+
+## Compile PE32 signatures.
+compileFiles "$SRC/pe/x86" "$OUT/pe/x86.yarac"
+compileFiles "$SRC/pe/arm" "$OUT/pe/arm.yarac"
+
+## Compile PE32+ signatures.
+compileFiles "$SRC/pe/x64" "$OUT/pe/x64.yarac"
+
+## Compile ELF signatures.
+compileFiles "$SRC/elf/x86" "$OUT/elf/x86.yarac"
+compileFiles "$SRC/elf/arm" "$OUT/elf/arm.yarac"
+compileFiles "$SRC/elf/ppc" "$OUT/elf/ppc.yarac"
+compileFiles "$SRC/elf/mips" "$OUT/elf/mips.yarac"
+
+## Compile ELF64 signatures.
+compileFiles "$SRC/elf/x64" "$OUT/elf/x64.yarac"
+compileFiles "$SRC/elf/arm64" "$OUT/elf/arm64.yarac"
+compileFiles "$SRC/elf/ppc64" "$OUT/elf/ppc64.yarac"
+compileFiles "$SRC/elf/mips64" "$OUT/elf/mips64.yarac"
+
+## Compile Mach-O signatures.
+compileFiles "$SRC/macho/x86" "$OUT/macho/x86.yarac"
+compileFiles "$SRC/macho/arm" "$OUT/macho/arm.yarac"
+compileFiles "$SRC/macho/ppc" "$OUT/macho/ppc.yarac"
+
+## Compile 64-bit Mach-O signatures.
+compileFiles "$SRC/macho/x64" "$OUT/macho/x64.yarac"
+compileFiles "$SRC/macho/ppc64" "$OUT/macho/ppc64.yarac"
+
+echo "signatures compiled successfully"
+exit
diff --git a/tests/utils/time_tests.cpp b/tests/utils/time_tests.cpp
index 30a62d36..a2b17303 100644
--- a/tests/utils/time_tests.cpp
+++ b/tests/utils/time_tests.cpp
@@ -4,8 +4,13 @@
 * @copyright (c) 2017 Avast Software, licensed under the MIT license
 */
 
+#include <cstdlib>
+#include <ctime>
+#include <string>
+
 #include <gtest/gtest.h>
 
+#include "retdec/utils/os.h"
 #include "retdec/utils/time.h"
 
 using namespace ::testing;
@@ -17,7 +22,58 @@ namespace tests {
 /**
 * @brief Tests for the @c time module.
 */
-class TimeTests: public Test {};
+class TimeTests: public Test {
+protected:
+	virtual void SetUp() override {
+		// We have to force a specific timezone to make the tests
+		// deterministic (#90).
+		changeTimezoneToUTC();
+	}
+
+	virtual void TearDown() override {
+		changeTimezoneBackToOriginalValue();
+	}
+
+	void changeTimezoneToUTC() {
+		// Store the original timezone so we can set it back in
+		// changeTimezoneBackToOriginalValue().
+		// Both Windows and POSIX use the same variable.
+		const auto TZ = std::getenv("TZ");
+		if (TZ) {
+			originalTZ = TZ;
+		}
+
+		#ifdef OS_WINDOWS
+			_putenv("TZ=UTC");
+			_tzset();
+		#else
+			setenv("TZ", "UTC", /*overwrite=*/1);
+			tzset();
+		#endif
+	}
+
+	void changeTimezoneBackToOriginalValue() {
+		#ifdef OS_WINDOWS
+			// Calling _putenv() specifying "VAR=" as a parameter (i.e. without
+			// the value) deletes the environment variable, which is what we
+			// want if originalTZ is empty.
+			const auto TZ_ENV = "TZ=" + originalTZ;
+			_putenv(TZ_ENV.c_str());
+			_tzset();
+		#else
+			if (originalTZ.empty()) {
+				unsetenv("TZ");
+			} else {
+				setenv("TZ", originalTZ.c_str(), /*overwrite=*/1);
+			}
+			tzset();
+		#endif
+	}
+
+private:
+	// Originally set timezone.
+	std::string originalTZ;
+};
 
 //
 // timestampToDate()
@@ -25,7 +81,7 @@ class TimeTests: public Test {};
 
 TEST_F(TimeTests,
 CorrectTimestampToDateConversion) {
-	EXPECT_EQ("2015-08-05 16:25:19", timestampToDate(std::time_t(1438784719)));
+	EXPECT_EQ("2015-08-05 14:25:19", timestampToDate(std::time_t(1438784719)));
 }
 
 } // namespace tests