Merge branch 'update-libarchive' into release
diff --git a/Auxiliary/bash-completion/cmake b/Auxiliary/bash-completion/cmake
index 557f243..6061129 100644
--- a/Auxiliary/bash-completion/cmake
+++ b/Auxiliary/bash-completion/cmake
@@ -121,14 +121,19 @@
                 grep -v "^cmake version " )' -- "$cur" ) )
             return
             ;;
+        --help-manual)
+            COMPREPLY=( $( compgen -W '$( cmake --help-manual-list 2>/dev/null|
+                grep -v "^cmake version " | sed -e "s/([0-9])$//" )' -- "$cur" ) )
+            return
+            ;;
         --help-module)
             COMPREPLY=( $( compgen -W '$( cmake --help-module-list 2>/dev/null|
                 grep -v "^cmake version " )' -- "$cur" ) )
             return
             ;;
          --help-policy)
-            COMPREPLY=( $( compgen -W '$( cmake --help-policies 2>/dev/null |
-                grep "^  CMP" 2>/dev/null )' -- "$cur" ) )
+            COMPREPLY=( $( compgen -W '$( cmake --help-policy-list 2>/dev/null |
+                grep -v "^cmake version " )' -- "$cur" ) )
             return
             ;;
          --help-property)
diff --git a/Auxiliary/bash-completion/cpack b/Auxiliary/bash-completion/cpack
index 05e0e93..cf5751f 100644
--- a/Auxiliary/bash-completion/cpack
+++ b/Auxiliary/bash-completion/cpack
@@ -48,6 +48,26 @@
                 grep -v "^cpack version " )' -- "$cur" ) )
             return
             ;;
+        --help-manual)
+            COMPREPLY=( $( compgen -W '$( cpack --help-manual-list 2>/dev/null|
+                grep -v "^cpack version " | sed -e "s/([0-9])$//" )' -- "$cur" ) )
+            return
+            ;;
+        --help-module)
+            COMPREPLY=( $( compgen -W '$( cpack --help-module-list 2>/dev/null|
+                grep -v "^cpack version " )' -- "$cur" ) )
+            return
+            ;;
+        --help-policy)
+            COMPREPLY=( $( compgen -W '$( cpack --help-policy-list 2>/dev/null |
+                grep -v "^cpack version " )' -- "$cur" ) )
+            return
+            ;;
+        --help-property)
+            COMPREPLY=( $( compgen -W '$( cpack --help-property-list \
+                2>/dev/null | grep -v "^cpack version " )' -- "$cur" ) )
+            return
+            ;;
         --help-variable)
             COMPREPLY=( $( compgen -W '$( cpack --help-variable-list \
                 2>/dev/null | grep -v "^cpack version " )' -- "$cur" ) )
diff --git a/Auxiliary/bash-completion/ctest b/Auxiliary/bash-completion/ctest
index 387672a..49343bb 100644
--- a/Auxiliary/bash-completion/ctest
+++ b/Auxiliary/bash-completion/ctest
@@ -72,11 +72,37 @@
             COMPREPLY=( $( compgen -W '0 1' -- "$cur" ) )
             return
             ;;
+
         --help-command)
             COMPREPLY=( $( compgen -W '$( ctest --help-command-list 2>/dev/null|
                 grep -v "^ctest version " )' -- "$cur" ) )
             return
             ;;
+        --help-manual)
+            COMPREPLY=( $( compgen -W '$( ctest --help-manual-list 2>/dev/null|
+                grep -v "^ctest version " | sed -e "s/([0-9])$//" )' -- "$cur" ) )
+            return
+            ;;
+        --help-module)
+            COMPREPLY=( $( compgen -W '$( ctest --help-module-list 2>/dev/null|
+                grep -v "^ctest version " )' -- "$cur" ) )
+            return
+            ;;
+        --help-policy)
+            COMPREPLY=( $( compgen -W '$( ctest --help-policy-list 2>/dev/null |
+                grep -v "^ctest version " )' -- "$cur" ) )
+            return
+            ;;
+        --help-property)
+            COMPREPLY=( $( compgen -W '$( ctest --help-property-list \
+                2>/dev/null | grep -v "^ctest version " )' -- "$cur" ) )
+            return
+            ;;
+        --help-variable)
+            COMPREPLY=( $( compgen -W '$( ctest --help-variable-list \
+                2>/dev/null | grep -v "^ctest version " )' -- "$cur" ) )
+            return
+            ;;
     esac
 
     if [[ "$cur" == -* ]]; then
diff --git a/Help/command/ctest_update.rst b/Help/command/ctest_update.rst
index 74af1f7..b205bca 100644
--- a/Help/command/ctest_update.rst
+++ b/Help/command/ctest_update.rst
@@ -25,3 +25,7 @@
   have otherwise printed to the console.  CTest will still report
   the new revision of the repository and any conflicting files
   that were found.
+
+The update always follows the version control branch currently checked
+out in the source directory.  See the :ref:`CTest Update Step`
+documentation for more information.
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 1179f56..e797333 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -589,6 +589,11 @@
   * `CTest Script`_ variable: :variable:`CTEST_GIT_COMMAND`
   * :module:`CTest` module variable: ``GITCOMMAND``
 
+  The source tree is updated by ``git fetch`` followed by
+  ``git reset --hard`` to the ``FETCH_HEAD``.  The result is the same
+  as ``git pull`` except that any local moficiations are overwritten.
+  Use ``GITUpdateCustom`` to specify a different approach.
+
 ``GITInitSubmodules``
   If set, CTest will update the repository's submodules before updating.
 
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
deleted file mode 100644
index e4cc01e..0000000
--- a/Help/release/dev/0-sample-topic.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-0-sample-topic
---------------
-
-* This is a sample release note for the change in a topic.
-  Developers should add similar notes for each topic branch
-  making a noteworthy change.  Each document should be named
-  and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index e93b880..92c3b63 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -5,8 +5,6 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
-.. include:: dev.txt
-
 Releases
 ========
 
diff --git a/Modules/Compiler/TI-C.cmake b/Modules/Compiler/TI-C.cmake
index 479666c..ebc79f4 100644
--- a/Modules/Compiler/TI-C.cmake
+++ b/Modules/Compiler/TI-C.cmake
@@ -7,4 +7,4 @@
 
 set(CMAKE_C_COMPILE_OBJECT  "<CMAKE_C_COMPILER> --compile_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
 set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
-set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_C_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
+set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index f589977..bc0d50b 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -345,7 +345,7 @@
 endmacro()
 
 # Try to find HDF5 using an installed hdf5-config.cmake
-if(NOT HDF5_ROOT AND NOT HDF5_FOUND)
+if(NOT HDF5_FOUND AND NOT HDF5_ROOT)
     find_package(HDF5 QUIET NO_MODULE)
     if( HDF5_FOUND)
         set(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR})
@@ -382,7 +382,7 @@
     endif()
 endif()
 
-if(NOT HDF5_ROOT AND NOT HDF5_FOUND)
+if(NOT HDF5_FOUND AND NOT HDF5_ROOT)
   set(_HDF5_NEED_TO_SEARCH False)
   set(HDF5_COMPILER_NO_INTERROGATE True)
   # Only search for languages we've enabled
@@ -488,12 +488,12 @@
   set(_HDF5_NEED_TO_SEARCH True)
 endif()
 
-if(HDF5_COMPILER_NO_INTERROGATE)
+if(NOT HDF5_FOUND AND HDF5_COMPILER_NO_INTERROGATE)
   # No arguments necessary, all languages can use the compiler wrappers
   set(HDF5_FOUND True)
   set(HDF5_METHOD "Included by compiler wrappers")
   set(HDF5_REQUIRED_VARS HDF5_METHOD)
-elseif(NOT _HDF5_NEED_TO_SEARCH)
+elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH)
   # Compiler wrappers aren't being used by the build but were found and used
   # to determine necessary include and library flags
   set(HDF5_INCLUDE_DIRS)
@@ -680,6 +680,13 @@
     endif()
 endif()
 
+# If HDF5_REQUIRED_VARS is empty at this point, then it's likely that
+# something external is trying to explicitly pass already found
+# locations
+if(NOT HDF5_REQUIRED_VARS)
+    set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS)
+endif()
+
 find_package_handle_standard_args(HDF5
     REQUIRED_VARS ${HDF5_REQUIRED_VARS}
     VERSION_VAR   HDF5_VERSION
diff --git a/Modules/FindLibArchive.cmake b/Modules/FindLibArchive.cmake
index 471a4f1..dd93041 100644
--- a/Modules/FindLibArchive.cmake
+++ b/Modules/FindLibArchive.cmake
@@ -42,14 +42,15 @@
 
 # Extract the version number from the header.
 if(LibArchive_INCLUDE_DIR AND EXISTS "${LibArchive_INCLUDE_DIR}/archive.h")
-  # The version string appears in one of two known formats in the header:
+  # The version string appears in one of three known formats in the header:
   #  #define ARCHIVE_LIBRARY_VERSION "libarchive 2.4.12"
   #  #define ARCHIVE_VERSION_STRING "libarchive 2.8.4"
-  # Match either format.
-  set(_LibArchive_VERSION_REGEX "^#define[ \t]+ARCHIVE[_A-Z]+VERSION[_A-Z]*[ \t]+\"libarchive +([0-9]+)\\.([0-9]+)\\.([0-9]+)[^\"]*\".*$")
+  #  #define ARCHIVE_VERSION_ONLY_STRING "3.2.0"
+  # Match any format.
+  set(_LibArchive_VERSION_REGEX "^#define[ \t]+ARCHIVE[_A-Z]+VERSION[_A-Z]*[ \t]+\"(libarchive +)?([0-9]+)\\.([0-9]+)\\.([0-9]+)[^\"]*\".*$")
   file(STRINGS "${LibArchive_INCLUDE_DIR}/archive.h" _LibArchive_VERSION_STRING LIMIT_COUNT 1 REGEX "${_LibArchive_VERSION_REGEX}")
   if(_LibArchive_VERSION_STRING)
-    string(REGEX REPLACE "${_LibArchive_VERSION_REGEX}" "\\1.\\2.\\3" LibArchive_VERSION "${_LibArchive_VERSION_STRING}")
+    string(REGEX REPLACE "${_LibArchive_VERSION_REGEX}" "\\2.\\3.\\4" LibArchive_VERSION "${_LibArchive_VERSION_STRING}")
   endif()
   unset(_LibArchive_VERSION_REGEX)
   unset(_LibArchive_VERSION_STRING)
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 644687c..b79e9df 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -591,12 +591,14 @@
    XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
 #]========================================]
 macro(pkg_check_modules _prefix _module0)
+  _pkgconfig_parse_options(_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target "${_module0}" ${ARGN})
   # check cached value
   if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
-    _pkgconfig_parse_options   (_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target "${_module0}" ${ARGN})
     _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} "${_prefix}" ${_pkg_modules})
 
     _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
+  elseif (${_prefix}_FOUND AND ${_imp_target})
+    _pkg_create_imp_target("${_prefix}" _no_cmake_path _no_cmake_environment_path)
   endif()
 endmacro()
 
@@ -619,10 +621,10 @@
     pkg_search_module (BAR     libxml-2.0 libxml2 libxml>=2)
 #]========================================]
 macro(pkg_search_module _prefix _module0)
+  _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target "${_module0}" ${ARGN})
   # check cached value
   if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
     set(_pkg_modules_found 0)
-    _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target "${_module0}" ${ARGN})
 
     if (NOT ${_pkg_is_silent})
       message(STATUS "Checking for one of the modules '${_pkg_modules_alt}'")
@@ -646,6 +648,8 @@
     endif()
 
     _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
+  elseif (${_prefix}_FOUND AND ${_imp_target})
+    _pkg_create_imp_target("${_prefix}" _no_cmake_path _no_cmake_environment_path)
   endif()
 endmacro()
 
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 11091b5..d167a13 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -240,6 +240,8 @@
 #  The QAxServer target (Windows only)
 # ``Qt4::QtDBus``
 #  The QtDBus target
+# ``Qt4::QtDeclarative``
+#  The QtDeclarative target
 # ``Qt4::QtDesigner``
 #  The QtDesigner target
 # ``Qt4::QtDesignerComponents``
diff --git a/Modules/Platform/SunOS-PathScale-C.cmake b/Modules/Platform/SunOS-PathScale-C.cmake
new file mode 100644
index 0000000..2f78da1
--- /dev/null
+++ b/Modules/Platform/SunOS-PathScale-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/SunOS-PathScale)
+__sunos_compiler_pathscale(C)
diff --git a/Modules/Platform/SunOS-PathScale-CXX.cmake b/Modules/Platform/SunOS-PathScale-CXX.cmake
new file mode 100644
index 0000000..bb79d86
--- /dev/null
+++ b/Modules/Platform/SunOS-PathScale-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/SunOS-PathScale)
+__sunos_compiler_pathscale(CXX)
diff --git a/Modules/Platform/SunOS-PathScale-Fortran.cmake b/Modules/Platform/SunOS-PathScale-Fortran.cmake
new file mode 100644
index 0000000..3c202f7
--- /dev/null
+++ b/Modules/Platform/SunOS-PathScale-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/SunOS-PathScale)
+__sunos_compiler_pathscale(Fortran)
diff --git a/Modules/Platform/SunOS-PathScale.cmake b/Modules/Platform/SunOS-PathScale.cmake
new file mode 100644
index 0000000..1afe56a
--- /dev/null
+++ b/Modules/Platform/SunOS-PathScale.cmake
@@ -0,0 +1,31 @@
+
+#=============================================================================
+# Copyright 2016 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__SUNOS_COMPILER_PATHSCALE)
+  return()
+endif()
+set(__SUNOS_COMPILER_PATHSCALE 1)
+
+macro(__sunos_compiler_pathscale lang)
+  # Shared library compile and link flags.
+  set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+  set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
+  set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+
+  set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-R")
+  set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
+  set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-h")
+endmacro()
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 1920a7c..6c254ed 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -305,7 +305,7 @@
     set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-D_DEBUG /MDd -gline-tables-only -fno-inline -O0 ${_RTC1}")
     set(CMAKE_${lang}_FLAGS_RELEASE_INIT "/MD -O2 -DNDEBUG")
     set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "/MD -gline-tables-only -O2 -fno-inline -DNDEBUG")
-    set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "/MD -Os -DNDEBUG")
+    set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "/MD -DNDEBUG") # TODO: Add '-Os' once VS generator maps it properly for Clang
   else()
     set(CMAKE_${lang}_FLAGS_INIT "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS /W3${_FLAGS_${lang}}")
     set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od ${_RTC1}")
diff --git a/README.rst b/README.rst
index 9599a04..4188ea0 100644
--- a/README.rst
+++ b/README.rst
@@ -89,7 +89,7 @@
 3. Finally, if the issue is not resolved by the above steps, open
    an entry in the `CMake Issue Tracker`_.
 
-.. _`CMake Issue Tracker`: https://cmake.org/Bug
+.. _`CMake Issue Tracker`: https://gitlab.kitware.com/cmake/cmake/issues
 
 Contributing
 ============
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 6c81449..172c9bc 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
-set(CMake_VERSION_MINOR 5)
-set(CMake_VERSION_PATCH 20160601)
-#set(CMake_VERSION_RC 1)
+set(CMake_VERSION_MINOR 6)
+set(CMake_VERSION_PATCH 0)
+set(CMake_VERSION_RC 2)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index c3c1468..c849d52 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -19,6 +19,7 @@
 #include <QApplication>
 #include <QDir>
 #include <QLocale>
+#include <QString>
 #include <QTextCodec>
 #include <QTranslator>
 #include <cmsys/CommandLineArguments.hxx>
@@ -40,6 +41,7 @@
 
 #if defined(Q_OS_MAC)
 static int cmOSXInstall(std::string dir);
+static void cmAddPluginPath();
 #endif
 
 int main(int argc, char** argv)
@@ -81,6 +83,15 @@
   }
 #endif
 
+// When we are on OSX and we are launching cmake-gui from a symlink, the
+// application will fail to launch as it can't find the qt.conf file which
+// tells it what the name of the plugin folder is. We need to add this path
+// BEFORE the application is constructed as that is what triggers the
+// searching for the platform plugins
+#if defined(Q_OS_MAC)
+  cmAddPluginPath();
+#endif
+
   QApplication app(argc, argv);
 
   setlocale(LC_NUMERIC, "C");
@@ -215,4 +226,27 @@
     ? 0
     : 1;
 }
+
+// Locate the PlugIns directory and add it to the QApplication library paths.
+// We need to resolve all symlinks so we have a known relative path between
+// MacOS/CMake and the PlugIns directory.
+//
+// Note we are using cmSystemTools since Qt can't provide the path to the
+// executable before the QApplication is created, and that is when plugin
+// searching occurs.
+static void cmAddPluginPath()
+{
+  std::string const& path = cmSystemTools::GetCMakeGUICommand();
+  if (path.empty()) {
+    return;
+  }
+  std::string const& realPath = cmSystemTools::GetRealPath(path);
+  QFileInfo appPath(QString::fromLocal8Bit(realPath.c_str()));
+  QDir pluginDir = appPath.dir();
+  bool const foundPluginDir = pluginDir.cd("../PlugIns");
+  if (foundPluginDir) {
+    QApplication::addLibraryPath(pluginDir.path());
+  }
+}
+
 #endif
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 2070b1f..589bf53 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -578,19 +578,20 @@
     }
 
     // the include directories for this target
-    std::set<std::string> uniqIncludeDirs;
+    std::vector<std::string> allIncludeDirs;
 
     std::vector<std::string> includes;
     lg->GetIncludeDirectories(includes, target, "C", buildType);
 
-    uniqIncludeDirs.insert(includes.begin(), includes.end());
+    allIncludeDirs.insert(allIncludeDirs.end(), includes.begin(),
+                          includes.end());
 
     std::string systemIncludeDirs = makefile->GetSafeDefinition(
       "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
     if (!systemIncludeDirs.empty()) {
       std::vector<std::string> dirs;
       cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
-      uniqIncludeDirs.insert(dirs.begin(), dirs.end());
+      allIncludeDirs.insert(allIncludeDirs.end(), dirs.begin(), dirs.end());
     }
 
     systemIncludeDirs = makefile->GetSafeDefinition(
@@ -598,13 +599,16 @@
     if (!systemIncludeDirs.empty()) {
       std::vector<std::string> dirs;
       cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
-      uniqIncludeDirs.insert(dirs.begin(), dirs.end());
+      allIncludeDirs.insert(allIncludeDirs.end(), dirs.begin(), dirs.end());
     }
 
-    for (std::set<std::string>::const_iterator dirIt = uniqIncludeDirs.begin();
-         dirIt != uniqIncludeDirs.end(); ++dirIt) {
+    std::vector<std::string>::const_iterator end =
+      cmRemoveDuplicates(allIncludeDirs);
+
+    for (std::vector<std::string>::const_iterator i = allIncludeDirs.begin();
+         i != end; ++i) {
       xml.StartElement("Add");
-      xml.Attribute("directory", *dirIt);
+      xml.Attribute("directory", *i);
       xml.EndElement();
     }
 
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 5e0d2b7..f435a1d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1131,7 +1131,9 @@
         // target because the configuration type may not be known at
         // CMake time.
         cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
-        gg->CreateGenerationObjects();
+        if (!gg->GetConfigureDoneCMP0026()) {
+          gg->CreateGenerationObjects();
+        }
         cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
         this->Properties.SetProperty(propLOCATION, gt->GetLocationForBuild());
       }
@@ -1150,7 +1152,9 @@
           prop, this->ImportedGetFullPath(configName, false).c_str());
       } else {
         cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
-        gg->CreateGenerationObjects();
+        if (!gg->GetConfigureDoneCMP0026()) {
+          gg->CreateGenerationObjects();
+        }
         cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
         this->Properties.SetProperty(
           prop, gt->GetFullPath(configName, false).c_str());
@@ -1168,7 +1172,9 @@
             prop, this->ImportedGetFullPath(configName, false).c_str());
         } else {
           cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
-          gg->CreateGenerationObjects();
+          if (!gg->GetConfigureDoneCMP0026()) {
+            gg->CreateGenerationObjects();
+          }
           cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
           this->Properties.SetProperty(
             prop, gt->GetFullPath(configName, false).c_str());
diff --git a/Source/cmVS14CLFlagTable.h b/Source/cmVS14CLFlagTable.h
index 4243f30..5812e79 100644
--- a/Source/cmVS14CLFlagTable.h
+++ b/Source/cmVS14CLFlagTable.h
@@ -16,7 +16,6 @@
 
   { "Optimization", "", "Custom", "Custom", 0 },
   { "Optimization", "Od", "Disabled", "Disabled", 0 },
-  { "Optimization", "Os", "Minimize Size", "MinSize", 0 },
   { "Optimization", "O1", "Minimize Size", "MinSpace", 0 },
   { "Optimization", "O2", "Maximize Speed", "MaxSpeed", 0 },
   { "Optimization", "Ox", "Full Optimization", "Full", 0 },
diff --git a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
index 5f929ff..85e137f 100644
--- a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
@@ -1,17 +1,18 @@
 set(foo_preinst "^echo default_preinst$")
-set(foo_preinst_permissions_regex "-rwxr-xr-x .*")
+# NOTE: optional dot at the end of permissions regex is for SELinux enabled systems
+set(foo_preinst_permissions_regex "-rwxr-xr-x\.? .*")
 set(foo_prerm "^echo default_prerm$")
-set(foo_prerm_permissions_regex "-rwxr-xr-x .*")
+set(foo_prerm_permissions_regex "-rwxr-xr-x\.? .*")
 verifyDebControl("${FOUND_FILE_1}" "foo" "preinst;prerm")
 
 set(bar_preinst "^echo bar_preinst$")
-set(bar_prerm_permissions_regex "-rwx------ .*")
+set(bar_preinst_permissions_regex "-rwx------\.? .*")
 set(bar_prerm "^echo bar_prerm$")
-set(bar_prerm_permissions_regex "-rwx------ .*")
+set(bar_prerm_permissions_regex "-rwx------\.? .*")
 verifyDebControl("${FOUND_FILE_2}" "bar" "preinst;prerm")
 
 set(bas_preinst "^echo default_preinst$")
-set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
+set(bas_preinst_permissions_regex "-rwxr-xr-x\.? .*")
 set(bas_prerm "^echo default_prerm$")
-set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
+set(bas_prerm_permissions_regex "-rwxr-xr-x\.? .*")
 verifyDebControl("${FOUND_FILE_3}" "bas" "preinst;prerm")
diff --git a/Tests/RunCMake/CPack/DEB/DEB_GENERATE_SHLIBS-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/DEB_GENERATE_SHLIBS-VerifyResult.cmake
index 8ccb628..b1952ef 100644
--- a/Tests/RunCMake/CPack/DEB/DEB_GENERATE_SHLIBS-VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/DEB/DEB_GENERATE_SHLIBS-VerifyResult.cmake
@@ -1,3 +1,4 @@
 set(shlibs_shlibs "^libtest_lib 0\\.8 generate_shlibs \\(\\= 0\\.1\\.1\\)\n$")
-set(shlibs_shlibs_permissions_regex "-rw-r--r-- .*")
+# optional dot at the end of permissions regex is for SELinux enabled systems
+set(shlibs_shlibs_permissions_regex "-rw-r--r--\.? .*")
 verifyDebControl("${FOUND_FILE_1}" "shlibs" "shlibs")
diff --git a/Tests/RunCMake/CPack/DEB/DEB_GENERATE_SHLIBS_LDCONFIG-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/DEB_GENERATE_SHLIBS_LDCONFIG-VerifyResult.cmake
index d04c641..422cfbe 100644
--- a/Tests/RunCMake/CPack/DEB/DEB_GENERATE_SHLIBS_LDCONFIG-VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/DEB/DEB_GENERATE_SHLIBS_LDCONFIG-VerifyResult.cmake
@@ -1,7 +1,8 @@
 set(shlibs_shlibs "^libtest_lib 0\\.8 generate_shlibs_ldconfig \\(>\\= 0\\.1\\.1\\)\n$")
-set(shlibs_shlibs_permissions_regex "-rw-r--r-- .*")
+# NOTE: optional dot at the end of permissions regex is for SELinux enabled systems
+set(shlibs_shlibs_permissions_regex "-rw-r--r--\.? .*")
 set(shlibs_postinst ".*ldconfig.*")
-set(shlibs_postinst_permissions_regex "-rwxr-xr-x .*")
+set(shlibs_postinst_permissions_regex "-rwxr-xr-x\.? .*")
 set(shlibs_postrm ".*ldconfig.*")
-set(shlibs_postrm_permissions_regex "-rwxr-xr-x .*")
+set(shlibs_postrm_permissions_regex "-rwxr-xr-x\.? .*")
 verifyDebControl("${FOUND_FILE_1}" "shlibs" "shlibs;postinst;postrm")
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 45175d8..625bab2 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -28,6 +28,7 @@
 run_cmake(COMPILE_LANGUAGE-unknown-lang)
 run_cmake(TARGET_FILE-recursion)
 run_cmake(OUTPUT_NAME-recursion)
+run_cmake(TARGET_PROPERTY-LOCATION)
 
 run_cmake(ImportedTarget-TARGET_PDB_FILE)
 if(LINKER_SUPPORTS_PDB)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt
new file mode 100644
index 0000000..e4dbb71
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0026 is not set: Disallow use of the LOCATION target property.
+  Run "cmake --help-policy CMP0026" for policy details.  Use the cmake_policy
+  command to set the policy and suppress this warning.
+
+  The LOCATION property should not be read from target "foo".  Use the target
+  name directly with add_custom_command, or use the generator expression
+  \$<TARGET_FILE>, as appropriate.
+
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake
new file mode 100644
index 0000000..8929cdb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_library(foo empty.c)
+add_custom_target(drive COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:foo,LOCATION>)
diff --git a/Utilities/Release/upload_release.cmake b/Utilities/Release/upload_release.cmake
index f5e325e..04a0cac 100644
--- a/Utilities/Release/upload_release.cmake
+++ b/Utilities/Release/upload_release.cmake
@@ -1,6 +1,6 @@
 set(CTEST_RUN_CURRENT_SCRIPT 0)
 if(NOT VERSION)
- set(VERSION 3.5)
+ set(VERSION 3.6)
 endif()
 if(NOT DEFINED PROJECT_PREFIX)
   set(PROJECT_PREFIX cmake-${VERSION})
diff --git a/Utilities/cmexpat/lib/expat.h b/Utilities/cmexpat/lib/expat.h
index ec62f14..5abcefd 100644
--- a/Utilities/cmexpat/lib/expat.h
+++ b/Utilities/cmexpat/lib/expat.h
@@ -973,9 +973,12 @@
 
 /* Exposing the memory handling functions used in Expat */
 XMLPARSEAPI(void *)
+XML_ATTR_MALLOC
+XML_ATTR_ALLOC_SIZE(2)
 XML_MemMalloc(XML_Parser parser, size_t size);
 
 XMLPARSEAPI(void *)
+XML_ATTR_ALLOC_SIZE(3)
 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
 
 XMLPARSEAPI(void)
diff --git a/Utilities/cmexpat/lib/expat_external.h b/Utilities/cmexpat/lib/expat_external.h
index b2be17b..07a3c5c 100644
--- a/Utilities/cmexpat/lib/expat_external.h
+++ b/Utilities/cmexpat/lib/expat_external.h
@@ -67,12 +67,26 @@
 #endif
 #endif  /* not defined XML_STATIC */
 
+#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
+#define XMLIMPORT __attribute__ ((visibility ("default")))
+#endif
 
 /* If we didn't define it above, define it away: */
 #ifndef XMLIMPORT
 #define XMLIMPORT
 #endif
 
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+#define XML_ATTR_MALLOC __attribute__((__malloc__))
+#else
+#define XML_ATTR_MALLOC
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#define XML_ATTR_ALLOC_SIZE(x)  __attribute__((__alloc_size__(x)))
+#else
+#define XML_ATTR_ALLOC_SIZE(x)
+#endif
 
 #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
 
diff --git a/Utilities/cmexpat/lib/internal.h b/Utilities/cmexpat/lib/internal.h
index dd54548..94cb98e 100644
--- a/Utilities/cmexpat/lib/internal.h
+++ b/Utilities/cmexpat/lib/internal.h
@@ -71,3 +71,25 @@
 #define inline
 #endif
 #endif
+
+#ifndef UNUSED_P
+# ifdef __GNUC__
+#  define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
+# else
+#  define UNUSED_P(p) UNUSED_ ## p
+# endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void
+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Utilities/cmexpat/lib/xmlparse.c b/Utilities/cmexpat/lib/xmlparse.c
index c0e8f6e..b56b66a 100644
--- a/Utilities/cmexpat/lib/xmlparse.c
+++ b/Utilities/cmexpat/lib/xmlparse.c
@@ -1730,7 +1730,8 @@
 #ifdef XML_CONTEXT_BYTES
     int keep;
 #endif  /* defined XML_CONTEXT_BYTES */
-    int neededSize = len + (int)(bufferEnd - bufferPtr);
+    /* Do not invoke signed arithmetic overflow: */
+    int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
     if (neededSize < 0) {
       errorCode = XML_ERROR_NO_MEMORY;
       return NULL;
@@ -1761,7 +1762,8 @@
       if (bufferSize == 0)
         bufferSize = INIT_BUFFER_SIZE;
       do {
-        bufferSize *= 2;
+        /* Do not invoke signed arithmetic overflow: */
+        bufferSize = (int) (2U * (unsigned) bufferSize);
       } while (bufferSize < neededSize && bufferSize > 0);
       if (bufferSize <= 0) {
         errorCode = XML_ERROR_NO_MEMORY;
@@ -2462,11 +2464,11 @@
           for (;;) {
             int bufSize;
             int convLen;
-            XmlConvert(enc,
+            const enum XML_Convert_Result convert_res = XmlConvert(enc,
                        &fromPtr, rawNameEnd,
                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
             convLen = (int)(toPtr - (XML_Char *)tag->buf);
-            if (fromPtr == rawNameEnd) {
+            if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
               tag->name.strLen = convLen;
               break;
             }
@@ -2687,11 +2689,11 @@
           if (MUST_CONVERT(enc, s)) {
             for (;;) {
               ICHAR *dataPtr = (ICHAR *)dataBuf;
-              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
               *eventEndPP = s;
               charDataHandler(handlerArg, dataBuf,
                               (int)(dataPtr - (ICHAR *)dataBuf));
-              if (s == next)
+              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
                 break;
               *eventPP = s;
             }
@@ -3297,11 +3299,11 @@
           if (MUST_CONVERT(enc, s)) {
             for (;;) {
               ICHAR *dataPtr = (ICHAR *)dataBuf;
-              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
               *eventEndPP = next;
               charDataHandler(handlerArg, dataBuf,
                               (int)(dataPtr - (ICHAR *)dataBuf));
-              if (s == next)
+              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
                 break;
               *eventPP = s;
             }
@@ -4960,9 +4962,9 @@
 
 static enum XML_Error PTRCALL
 errorProcessor(XML_Parser parser,
-               const char *s,
-               const char *end,
-               const char **nextPtr)
+               const char *UNUSED_P(s),
+               const char *UNUSED_P(end),
+               const char **UNUSED_P(nextPtr))
 {
   return errorCode;
 }
@@ -5378,6 +5380,7 @@
               const char *s, const char *end)
 {
   if (MUST_CONVERT(enc, s)) {
+    enum XML_Convert_Result convert_res;
     const char **eventPP;
     const char **eventEndPP;
     if (enc == encoding) {
@@ -5390,11 +5393,11 @@
     }
     do {
       ICHAR *dataPtr = (ICHAR *)dataBuf;
-      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+      convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
       *eventEndPP = s;
       defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
       *eventPP = s;
-    } while (s != end);
+    } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
   }
   else
     defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
@@ -6199,8 +6202,8 @@
   if (!pool->ptr && !poolGrow(pool))
     return NULL;
   for (;;) {
-    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
-    if (ptr == end)
+    const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+    if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
       break;
     if (!poolGrow(pool))
       return NULL;
@@ -6284,8 +6287,13 @@
     }
   }
   if (pool->blocks && pool->start == pool->blocks->s) {
-    int blockSize = (int)(pool->end - pool->start)*2;
-    BLOCK *temp = (BLOCK *)
+    BLOCK *temp;
+    int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
+
+    if (blockSize < 0)
+      return XML_FALSE;
+
+    temp = (BLOCK *)
       pool->mem->realloc_fcn(pool->blocks,
                              (offsetof(BLOCK, s)
                               + blockSize * sizeof(XML_Char)));
@@ -6300,6 +6308,10 @@
   else {
     BLOCK *tem;
     int blockSize = (int)(pool->end - pool->start);
+
+    if (blockSize < 0)
+      return XML_FALSE;
+
     if (blockSize < INIT_BLOCK_SIZE)
       blockSize = INIT_BLOCK_SIZE;
     else
diff --git a/Utilities/cmexpat/lib/xmlrole.c b/Utilities/cmexpat/lib/xmlrole.c
index f6e66ab..4e79ffd 100644
--- a/Utilities/cmexpat/lib/xmlrole.c
+++ b/Utilities/cmexpat/lib/xmlrole.c
@@ -195,9 +195,9 @@
 static int PTRCALL
 prolog2(PROLOG_STATE *state,
         int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
+        const char *UNUSED_P(ptr),
+        const char *UNUSED_P(end),
+        const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -216,9 +216,9 @@
 static int PTRCALL
 doctype0(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -264,9 +264,9 @@
 static int PTRCALL
 doctype2(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -281,9 +281,9 @@
 static int PTRCALL
 doctype3(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -298,9 +298,9 @@
 static int PTRCALL
 doctype4(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -318,9 +318,9 @@
 static int PTRCALL
 doctype5(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -437,9 +437,9 @@
 static int PTRCALL
 entity0(PROLOG_STATE *state,
         int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
+        const char *UNUSED_P(ptr),
+        const char *UNUSED_P(end),
+        const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -457,9 +457,9 @@
 static int PTRCALL
 entity1(PROLOG_STATE *state,
         int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
+        const char *UNUSED_P(ptr),
+        const char *UNUSED_P(end),
+        const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -502,9 +502,9 @@
 static int PTRCALL
 entity3(PROLOG_STATE *state,
         int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
+        const char *UNUSED_P(ptr),
+        const char *UNUSED_P(end),
+        const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -519,9 +519,9 @@
 static int PTRCALL
 entity4(PROLOG_STATE *state,
         int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
+        const char *UNUSED_P(ptr),
+        const char *UNUSED_P(end),
+        const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -559,9 +559,9 @@
 static int PTRCALL
 entity6(PROLOG_STATE *state,
         int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
+        const char *UNUSED_P(ptr),
+        const char *UNUSED_P(end),
+        const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -605,9 +605,9 @@
 static int PTRCALL
 entity8(PROLOG_STATE *state,
         int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
+        const char *UNUSED_P(ptr),
+        const char *UNUSED_P(end),
+        const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -622,9 +622,9 @@
 static int PTRCALL
 entity9(PROLOG_STATE *state,
         int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
+        const char *UNUSED_P(ptr),
+        const char *UNUSED_P(end),
+        const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -639,9 +639,9 @@
 static int PTRCALL
 entity10(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -656,9 +656,9 @@
 static int PTRCALL
 notation0(PROLOG_STATE *state,
           int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
+          const char *UNUSED_P(ptr),
+          const char *UNUSED_P(end),
+          const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -697,9 +697,9 @@
 static int PTRCALL
 notation2(PROLOG_STATE *state,
           int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
+          const char *UNUSED_P(ptr),
+          const char *UNUSED_P(end),
+          const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -714,9 +714,9 @@
 static int PTRCALL
 notation3(PROLOG_STATE *state,
           int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
+          const char *UNUSED_P(ptr),
+          const char *UNUSED_P(end),
+          const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -732,9 +732,9 @@
 static int PTRCALL
 notation4(PROLOG_STATE *state,
           int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
+          const char *UNUSED_P(ptr),
+          const char *UNUSED_P(end),
+          const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -753,9 +753,9 @@
 static int PTRCALL
 attlist0(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -771,9 +771,9 @@
 static int PTRCALL
 attlist1(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -833,9 +833,9 @@
 static int PTRCALL
 attlist3(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -852,9 +852,9 @@
 static int PTRCALL
 attlist4(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -872,9 +872,9 @@
 static int PTRCALL
 attlist5(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -889,9 +889,9 @@
 static int PTRCALL
 attlist6(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -906,9 +906,9 @@
 static int PTRCALL
 attlist7(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -967,9 +967,9 @@
 static int PTRCALL
 attlist9(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -984,9 +984,9 @@
 static int PTRCALL
 element0(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1072,9 +1072,9 @@
 static int PTRCALL
 element3(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1097,9 +1097,9 @@
 static int PTRCALL
 element4(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1115,9 +1115,9 @@
 static int PTRCALL
 element5(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1136,9 +1136,9 @@
 static int PTRCALL
 element6(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1166,9 +1166,9 @@
 static int PTRCALL
 element7(PROLOG_STATE *state,
          int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
+         const char *UNUSED_P(ptr),
+         const char *UNUSED_P(end),
+         const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1240,9 +1240,9 @@
 static int PTRCALL
 condSect1(PROLOG_STATE *state,
           int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
+          const char *UNUSED_P(ptr),
+          const char *UNUSED_P(end),
+          const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1258,9 +1258,9 @@
 static int PTRCALL
 condSect2(PROLOG_STATE *state,
           int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
+          const char *UNUSED_P(ptr),
+          const char *UNUSED_P(end),
+          const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1277,9 +1277,9 @@
 static int PTRCALL
 declClose(PROLOG_STATE *state,
           int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
+          const char *UNUSED_P(ptr),
+          const char *UNUSED_P(end),
+          const ENCODING *UNUSED_P(enc))
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1292,11 +1292,11 @@
 }
 
 static int PTRCALL
-error(PROLOG_STATE *state,
-      int tok,
-      const char *ptr,
-      const char *end,
-      const ENCODING *enc)
+error(PROLOG_STATE *UNUSED_P(state),
+      int UNUSED_P(tok),
+      const char *UNUSED_P(ptr),
+      const char *UNUSED_P(end),
+      const ENCODING *UNUSED_P(enc))
 {
   return XML_ROLE_NONE;
 }
diff --git a/Utilities/cmexpat/lib/xmltok.c b/Utilities/cmexpat/lib/xmltok.c
index 814fe92..4195279 100644
--- a/Utilities/cmexpat/lib/xmltok.c
+++ b/Utilities/cmexpat/lib/xmltok.c
@@ -46,7 +46,7 @@
 #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
 
 #define UCS2_GET_NAMING(pages, hi, lo) \
-   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
 
 /* A 2 byte UTF-8 representation splits the characters 11 bits between
    the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into
@@ -56,7 +56,7 @@
     (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
                       + ((((byte)[0]) & 3) << 1) \
                       + ((((byte)[1]) >> 5) & 1)] \
-         & (1 << (((byte)[1]) & 0x1F)))
+         & (1u << (((byte)[1]) & 0x1F)))
 
 /* A 3 byte UTF-8 representation splits the characters 16 bits between
    the bottom 4, 6 and 6 bits of the bytes.  We need 8 bits to index
@@ -69,7 +69,7 @@
                        << 3) \
                       + ((((byte)[1]) & 3) << 1) \
                       + ((((byte)[2]) >> 5) & 1)] \
-         & (1 << (((byte)[2]) & 0x1F)))
+         & (1u << (((byte)[2]) & 0x1F)))
 
 #define UTF8_GET_NAMING(pages, p, n) \
   ((n) == 2 \
@@ -122,19 +122,19 @@
     ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
 
 static int PTRFASTCALL
-isNever(const ENCODING *enc, const char *p)
+isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p))
 {
   return 0;
 }
 
 static int PTRFASTCALL
-utf8_isName2(const ENCODING *enc, const char *p)
+utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p)
 {
   return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
 }
 
 static int PTRFASTCALL
-utf8_isName3(const ENCODING *enc, const char *p)
+utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p)
 {
   return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
 }
@@ -142,13 +142,13 @@
 #define utf8_isName4 isNever
 
 static int PTRFASTCALL
-utf8_isNmstrt2(const ENCODING *enc, const char *p)
+utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p)
 {
   return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
 }
 
 static int PTRFASTCALL
-utf8_isNmstrt3(const ENCODING *enc, const char *p)
+utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p)
 {
   return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
 }
@@ -156,19 +156,19 @@
 #define utf8_isNmstrt4 isNever
 
 static int PTRFASTCALL
-utf8_isInvalid2(const ENCODING *enc, const char *p)
+utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p)
 {
   return UTF8_INVALID2((const unsigned char *)p);
 }
 
 static int PTRFASTCALL
-utf8_isInvalid3(const ENCODING *enc, const char *p)
+utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p)
 {
   return UTF8_INVALID3((const unsigned char *)p);
 }
 
 static int PTRFASTCALL
-utf8_isInvalid4(const ENCODING *enc, const char *p)
+utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p)
 {
   return UTF8_INVALID4((const unsigned char *)p);
 }
@@ -329,39 +329,89 @@
   UTF8_cval4 = 0xf0
 };
 
-static void PTRCALL
-utf8_toUtf8(const ENCODING *enc,
+void
+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef)
+{
+  const char * fromLim = *fromLimRef;
+  size_t walked = 0;
+  for (; fromLim > from; fromLim--, walked++) {
+    const unsigned char prev = (unsigned char)fromLim[-1];
+    if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
+      if (walked + 1 >= 4) {
+        fromLim += 4 - 1;
+        break;
+      } else {
+        walked = 0;
+      }
+    } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
+      if (walked + 1 >= 3) {
+        fromLim += 3 - 1;
+        break;
+      } else {
+        walked = 0;
+      }
+    } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
+      if (walked + 1 >= 2) {
+        fromLim += 2 - 1;
+        break;
+      } else {
+        walked = 0;
+      }
+    } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
+      break;
+    }
+  }
+  *fromLimRef = fromLim;
+}
+
+static enum XML_Convert_Result PTRCALL
+utf8_toUtf8(const ENCODING *UNUSED_P(enc),
             const char **fromP, const char *fromLim,
             char **toP, const char *toLim)
 {
+  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
   char *to;
   const char *from;
   if (fromLim - *fromP > toLim - *toP) {
     /* Avoid copying partial characters. */
-    for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
-      if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
-        break;
+    res = XML_CONVERT_OUTPUT_EXHAUSTED;
+    fromLim = *fromP + (toLim - *toP);
+    align_limit_to_full_utf8_characters(*fromP, &fromLim);
   }
-  for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+  for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)
     *to = *from;
   *fromP = from;
   *toP = to;
+
+  if ((to == toLim) && (from < fromLim))
+    return XML_CONVERT_OUTPUT_EXHAUSTED;
+  else
+    return res;
 }
 
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
 utf8_toUtf16(const ENCODING *enc,
              const char **fromP, const char *fromLim,
              unsigned short **toP, const unsigned short *toLim)
 {
+  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
   unsigned short *to = *toP;
   const char *from = *fromP;
-  while (from != fromLim && to != toLim) {
+  while (from < fromLim && to < toLim) {
     switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
     case BT_LEAD2:
+      if (fromLim - from < 2) {
+        res = XML_CONVERT_INPUT_INCOMPLETE;
+        break;
+      }
       *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
       from += 2;
       break;
     case BT_LEAD3:
+      if (fromLim - from < 3) {
+        res = XML_CONVERT_INPUT_INCOMPLETE;
+        break;
+      }
       *to++ = (unsigned short)(((from[0] & 0xf) << 12)
                                | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
       from += 3;
@@ -369,8 +419,14 @@
     case BT_LEAD4:
       {
         unsigned long n;
-        if (to + 1 == toLim)
+        if (toLim - to < 2) {
+          res = XML_CONVERT_OUTPUT_EXHAUSTED;
           goto after;
+        }
+        if (fromLim - from < 4) {
+          res = XML_CONVERT_INPUT_INCOMPLETE;
+          goto after;
+        }
         n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
             | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
         n -= 0x10000;
@@ -388,6 +444,7 @@
 after:
   *fromP = from;
   *toP = to;
+  return res;
 }
 
 #ifdef XML_NS
@@ -436,38 +493,43 @@
   STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
 };
 
-static void PTRCALL
-latin1_toUtf8(const ENCODING *enc,
+static enum XML_Convert_Result PTRCALL
+latin1_toUtf8(const ENCODING *UNUSED_P(enc),
               const char **fromP, const char *fromLim,
               char **toP, const char *toLim)
 {
   for (;;) {
     unsigned char c;
     if (*fromP == fromLim)
-      break;
+      return XML_CONVERT_COMPLETED;
     c = (unsigned char)**fromP;
     if (c & 0x80) {
       if (toLim - *toP < 2)
-        break;
+        return XML_CONVERT_OUTPUT_EXHAUSTED;
       *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
       *(*toP)++ = (char)((c & 0x3f) | 0x80);
       (*fromP)++;
     }
     else {
       if (*toP == toLim)
-        break;
+        return XML_CONVERT_OUTPUT_EXHAUSTED;
       *(*toP)++ = *(*fromP)++;
     }
   }
 }
 
-static void PTRCALL
-latin1_toUtf16(const ENCODING *enc,
+static enum XML_Convert_Result PTRCALL
+latin1_toUtf16(const ENCODING *UNUSED_P(enc),
                const char **fromP, const char *fromLim,
                unsigned short **toP, const unsigned short *toLim)
 {
-  while (*fromP != fromLim && *toP != toLim)
+  while (*fromP < fromLim && *toP < toLim)
     *(*toP)++ = (unsigned char)*(*fromP)++;
+
+  if ((*toP == toLim) && (*fromP < fromLim))
+    return XML_CONVERT_OUTPUT_EXHAUSTED;
+  else
+    return XML_CONVERT_COMPLETED;
 }
 
 #ifdef XML_NS
@@ -494,13 +556,18 @@
   STANDARD_VTABLE(sb_) NULL_VTABLE
 };
 
-static void PTRCALL
-ascii_toUtf8(const ENCODING *enc,
+static enum XML_Convert_Result PTRCALL
+ascii_toUtf8(const ENCODING *UNUSED_P(enc),
              const char **fromP, const char *fromLim,
              char **toP, const char *toLim)
 {
-  while (*fromP != fromLim && *toP != toLim)
+  while (*fromP < fromLim && *toP < toLim)
     *(*toP)++ = *(*fromP)++;
+
+  if ((*toP == toLim) && (*fromP < fromLim))
+    return XML_CONVERT_OUTPUT_EXHAUSTED;
+  else
+    return XML_CONVERT_COMPLETED;
 }
 
 #ifdef XML_NS
@@ -547,13 +614,14 @@
 }
 
 #define DEFINE_UTF16_TO_UTF8(E) \
-static void  PTRCALL \
-E ## toUtf8(const ENCODING *enc, \
+static enum XML_Convert_Result  PTRCALL \
+E ## toUtf8(const ENCODING *UNUSED_P(enc), \
             const char **fromP, const char *fromLim, \
             char **toP, const char *toLim) \
 { \
-  const char *from; \
-  for (from = *fromP; from != fromLim; from += 2) { \
+  const char *from = *fromP; \
+  fromLim = from + (((fromLim - from) >> 1) << 1);  /* shrink to even */ \
+  for (; from < fromLim; from += 2) { \
     int plane; \
     unsigned char lo2; \
     unsigned char lo = GET_LO(from); \
@@ -563,7 +631,7 @@
       if (lo < 0x80) { \
         if (*toP == toLim) { \
           *fromP = from; \
-          return; \
+          return XML_CONVERT_OUTPUT_EXHAUSTED; \
         } \
         *(*toP)++ = lo; \
         break; \
@@ -573,7 +641,7 @@
     case 0x4: case 0x5: case 0x6: case 0x7: \
       if (toLim -  *toP < 2) { \
         *fromP = from; \
-        return; \
+        return XML_CONVERT_OUTPUT_EXHAUSTED; \
       } \
       *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
       *(*toP)++ = ((lo & 0x3f) | 0x80); \
@@ -581,7 +649,7 @@
     default: \
       if (toLim -  *toP < 3)  { \
         *fromP = from; \
-        return; \
+        return XML_CONVERT_OUTPUT_EXHAUSTED; \
       } \
       /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
       *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
@@ -591,7 +659,11 @@
     case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
       if (toLim -  *toP < 4) { \
         *fromP = from; \
-        return; \
+        return XML_CONVERT_OUTPUT_EXHAUSTED; \
+      } \
+      if (fromLim - from < 4) { \
+        *fromP = from; \
+        return XML_CONVERT_INPUT_INCOMPLETE; \
       } \
       plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
       *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
@@ -607,20 +679,32 @@
     } \
   } \
   *fromP = from; \
+  if (from < fromLim) \
+    return XML_CONVERT_INPUT_INCOMPLETE; \
+  else \
+    return XML_CONVERT_COMPLETED; \
 }
 
 #define DEFINE_UTF16_TO_UTF16(E) \
-static void  PTRCALL \
-E ## toUtf16(const ENCODING *enc, \
+static enum XML_Convert_Result  PTRCALL \
+E ## toUtf16(const ENCODING *UNUSED_P(enc), \
              const char **fromP, const char *fromLim, \
              unsigned short **toP, const unsigned short *toLim) \
 { \
+  enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
+  fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1);  /* shrink to even */ \
   /* Avoid copying first half only of surrogate */ \
   if (fromLim - *fromP > ((toLim - *toP) << 1) \
-      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
     fromLim -= 2; \
-  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+    res = XML_CONVERT_INPUT_INCOMPLETE; \
+  } \
+  for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
     *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+  if ((*toP == toLim) && (*fromP < fromLim)) \
+    return XML_CONVERT_OUTPUT_EXHAUSTED; \
+  else \
+    return res; \
 }
 
 #define SET2(ptr, ch) \
@@ -949,7 +1033,7 @@
 }
 
 static void PTRCALL
-initUpdatePosition(const ENCODING *enc, const char *ptr,
+initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr,
                    const char *end, POSITION *pos)
 {
   normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
@@ -1299,7 +1383,7 @@
   return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
 }
 
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
 unknown_toUtf8(const ENCODING *enc,
                const char **fromP, const char *fromLim,
                char **toP, const char *toLim)
@@ -1310,21 +1394,21 @@
     const char *utf8;
     int n;
     if (*fromP == fromLim)
-      break;
+      return XML_CONVERT_COMPLETED;
     utf8 = uenc->utf8[(unsigned char)**fromP];
     n = *utf8++;
     if (n == 0) {
       int c = uenc->convert(uenc->userData, *fromP);
       n = XmlUtf8Encode(c, buf);
       if (n > toLim - *toP)
-        break;
+        return XML_CONVERT_OUTPUT_EXHAUSTED;
       utf8 = buf;
       *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
                  - (BT_LEAD2 - 2));
     }
     else {
       if (n > toLim - *toP)
-        break;
+        return XML_CONVERT_OUTPUT_EXHAUSTED;
       (*fromP)++;
     }
     do {
@@ -1333,13 +1417,13 @@
   }
 }
 
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
 unknown_toUtf16(const ENCODING *enc,
                 const char **fromP, const char *fromLim,
                 unsigned short **toP, const unsigned short *toLim)
 {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
-  while (*fromP != fromLim && *toP != toLim) {
+  while (*fromP < fromLim && *toP < toLim) {
     unsigned short c = uenc->utf16[(unsigned char)**fromP];
     if (c == 0) {
       c = (unsigned short)
@@ -1351,6 +1435,11 @@
       (*fromP)++;
     *(*toP)++ = c;
   }
+
+  if ((*toP == toLim) && (*fromP < fromLim))
+    return XML_CONVERT_OUTPUT_EXHAUSTED;
+  else
+    return XML_CONVERT_COMPLETED;
 }
 
 ENCODING *
@@ -1514,7 +1603,7 @@
 {
   const ENCODING **encPtr;
 
-  if (ptr == end)
+  if (ptr >= end)
     return XML_TOK_NONE;
   encPtr = enc->encPtr;
   if (ptr + 1 == end) {
diff --git a/Utilities/cmexpat/lib/xmltok.h b/Utilities/cmexpat/lib/xmltok.h
index ca867aa..752007e 100644
--- a/Utilities/cmexpat/lib/xmltok.h
+++ b/Utilities/cmexpat/lib/xmltok.h
@@ -130,6 +130,12 @@
                                const char *,
                                const char **);
 
+enum XML_Convert_Result {
+  XML_CONVERT_COMPLETED = 0,
+  XML_CONVERT_INPUT_INCOMPLETE = 1,
+  XML_CONVERT_OUTPUT_EXHAUSTED = 2  /* and therefore potentially input remaining as well */
+};
+
 struct encoding {
   SCANNER scanners[XML_N_STATES];
   SCANNER literalScanners[XML_N_LITERAL_TYPES];
@@ -158,12 +164,12 @@
                             const char *ptr,
                             const char *end,
                             const char **badPtr);
-  void (PTRCALL *utf8Convert)(const ENCODING *enc,
+  enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
                               const char **fromP,
                               const char *fromLim,
                               char **toP,
                               const char *toLim);
-  void (PTRCALL *utf16Convert)(const ENCODING *enc,
+  enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
                                const char **fromP,
                                const char *fromLim,
                                unsigned short **toP,
diff --git a/Utilities/cmexpat/lib/xmltok_impl.c b/Utilities/cmexpat/lib/xmltok_impl.c
index 9c2895b..fd0ee22 100644
--- a/Utilities/cmexpat/lib/xmltok_impl.c
+++ b/Utilities/cmexpat/lib/xmltok_impl.c
@@ -87,27 +87,45 @@
 #define PREFIX(ident) ident
 #endif
 
+
+#define HAS_CHARS(enc, ptr, end, count) \
+    (end - ptr >= count * MINBPC(enc))
+
+#define HAS_CHAR(enc, ptr, end) \
+    HAS_CHARS(enc, ptr, end, 1)
+
+#define REQUIRE_CHARS(enc, ptr, end, count) \
+    { \
+      if (! HAS_CHARS(enc, ptr, end, count)) { \
+        return XML_TOK_PARTIAL; \
+      } \
+    }
+
+#define REQUIRE_CHAR(enc, ptr, end) \
+    REQUIRE_CHARS(enc, ptr, end, 1)
+
+
 /* ptr points to character following "<!-" */
 
 static int PTRCALL
 PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
                     const char *end, const char **nextTokPtr)
 {
-  if (ptr != end) {
+  if (HAS_CHAR(enc, ptr, end)) {
     if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
       *nextTokPtr = ptr;
       return XML_TOK_INVALID;
     }
     ptr += MINBPC(enc);
-    while (ptr != end) {
+    while (HAS_CHAR(enc, ptr, end)) {
       switch (BYTE_TYPE(enc, ptr)) {
       INVALID_CASES(ptr, nextTokPtr)
       case BT_MINUS:
-        if ((ptr += MINBPC(enc)) == end)
-          return XML_TOK_PARTIAL;
+        ptr += MINBPC(enc);
+        REQUIRE_CHAR(enc, ptr, end);
         if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
-          if ((ptr += MINBPC(enc)) == end)
-            return XML_TOK_PARTIAL;
+          ptr += MINBPC(enc);
+          REQUIRE_CHAR(enc, ptr, end);
           if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
             *nextTokPtr = ptr;
             return XML_TOK_INVALID;
@@ -131,8 +149,7 @@
 PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
                  const char *end, const char **nextTokPtr)
 {
-  if (ptr == end)
-    return XML_TOK_PARTIAL;
+  REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
   case BT_MINUS:
     return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -147,11 +164,10 @@
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     case BT_PERCNT:
-      if (ptr + MINBPC(enc) == end)
-        return XML_TOK_PARTIAL;
+      REQUIRE_CHARS(enc, ptr, end, 2);
       /* don't allow <!ENTITY% foo "whatever"> */
       switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
       case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
@@ -175,7 +191,7 @@
 }
 
 static int PTRCALL
-PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
+PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
                       const char *end, int *tokPtr)
 {
   int upper = 0;
@@ -225,15 +241,14 @@
 {
   int tok;
   const char *target = ptr;
-  if (ptr == end)
-    return XML_TOK_PARTIAL;
+  REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   default:
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_S: case BT_CR: case BT_LF:
@@ -242,13 +257,12 @@
         return XML_TOK_INVALID;
       }
       ptr += MINBPC(enc);
-      while (ptr != end) {
+      while (HAS_CHAR(enc, ptr, end)) {
         switch (BYTE_TYPE(enc, ptr)) {
         INVALID_CASES(ptr, nextTokPtr)
         case BT_QUEST:
           ptr += MINBPC(enc);
-          if (ptr == end)
-            return XML_TOK_PARTIAL;
+          REQUIRE_CHAR(enc, ptr, end);
           if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
             *nextTokPtr = ptr + MINBPC(enc);
             return tok;
@@ -266,8 +280,7 @@
         return XML_TOK_INVALID;
       }
       ptr += MINBPC(enc);
-      if (ptr == end)
-        return XML_TOK_PARTIAL;
+      REQUIRE_CHAR(enc, ptr, end);
       if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         *nextTokPtr = ptr + MINBPC(enc);
         return tok;
@@ -282,15 +295,14 @@
 }
 
 static int PTRCALL
-PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
+PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
                          const char *end, const char **nextTokPtr)
 {
   static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
                                      ASCII_T, ASCII_A, ASCII_LSQB };
   int i;
   /* CDATA[ */
-  if (end - ptr < 6 * MINBPC(enc))
-    return XML_TOK_PARTIAL;
+  REQUIRE_CHARS(enc, ptr, end, 6);
   for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
     if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
       *nextTokPtr = ptr;
@@ -305,7 +317,7 @@
 PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
                         const char *end, const char **nextTokPtr)
 {
-  if (ptr == end)
+  if (ptr >= end)
     return XML_TOK_NONE;
   if (MINBPC(enc) > 1) {
     size_t n = end - ptr;
@@ -319,13 +331,11 @@
   switch (BYTE_TYPE(enc, ptr)) {
   case BT_RSQB:
     ptr += MINBPC(enc);
-    if (ptr == end)
-      return XML_TOK_PARTIAL;
+    REQUIRE_CHAR(enc, ptr, end);
     if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
       break;
     ptr += MINBPC(enc);
-    if (ptr == end)
-      return XML_TOK_PARTIAL;
+    REQUIRE_CHAR(enc, ptr, end);
     if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
       ptr -= MINBPC(enc);
       break;
@@ -334,8 +344,7 @@
     return XML_TOK_CDATA_SECT_CLOSE;
   case BT_CR:
     ptr += MINBPC(enc);
-    if (ptr == end)
-      return XML_TOK_PARTIAL;
+    REQUIRE_CHAR(enc, ptr, end);
     if (BYTE_TYPE(enc, ptr) == BT_LF)
       ptr += MINBPC(enc);
     *nextTokPtr = ptr;
@@ -348,7 +357,7 @@
     ptr += MINBPC(enc);
     break;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: \
@@ -383,19 +392,18 @@
 PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
                    const char *end, const char **nextTokPtr)
 {
-  if (ptr == end)
-    return XML_TOK_PARTIAL;
+  REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   default:
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_S: case BT_CR: case BT_LF:
-      for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
         switch (BYTE_TYPE(enc, ptr)) {
         case BT_S: case BT_CR: case BT_LF:
           break;
@@ -432,7 +440,7 @@
 PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
                        const char *end, const char **nextTokPtr)
 {
-  if (ptr != end) {
+  if (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     case BT_DIGIT:
     case BT_HEX:
@@ -441,7 +449,7 @@
       *nextTokPtr = ptr;
       return XML_TOK_INVALID;
     }
-    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+    for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_DIGIT:
       case BT_HEX:
@@ -464,7 +472,7 @@
 PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
                     const char *end, const char **nextTokPtr)
 {
-  if (ptr != end) {
+  if (HAS_CHAR(enc, ptr, end)) {
     if (CHAR_MATCHES(enc, ptr, ASCII_x))
       return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
     switch (BYTE_TYPE(enc, ptr)) {
@@ -474,7 +482,7 @@
       *nextTokPtr = ptr;
       return XML_TOK_INVALID;
     }
-    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+    for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_DIGIT:
         break;
@@ -496,8 +504,7 @@
 PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
                 const char **nextTokPtr)
 {
-  if (ptr == end)
-    return XML_TOK_PARTIAL;
+  REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   case BT_NUM:
@@ -506,7 +513,7 @@
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_SEMI:
@@ -529,7 +536,7 @@
 #ifdef XML_NS
   int hadColon = 0;
 #endif
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
 #ifdef XML_NS
@@ -540,8 +547,7 @@
       }
       hadColon = 1;
       ptr += MINBPC(enc);
-      if (ptr == end)
-        return XML_TOK_PARTIAL;
+      REQUIRE_CHAR(enc, ptr, end);
       switch (BYTE_TYPE(enc, ptr)) {
       CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
       default:
@@ -555,8 +561,7 @@
         int t;
 
         ptr += MINBPC(enc);
-        if (ptr == end)
-          return XML_TOK_PARTIAL;
+        REQUIRE_CHAR(enc, ptr, end);
         t = BYTE_TYPE(enc, ptr);
         if (t == BT_EQUALS)
           break;
@@ -579,8 +584,7 @@
 #endif
         for (;;) {
           ptr += MINBPC(enc);
-          if (ptr == end)
-            return XML_TOK_PARTIAL;
+          REQUIRE_CHAR(enc, ptr, end);
           open = BYTE_TYPE(enc, ptr);
           if (open == BT_QUOT || open == BT_APOS)
             break;
@@ -598,8 +602,7 @@
         /* in attribute value */
         for (;;) {
           int t;
-          if (ptr == end)
-            return XML_TOK_PARTIAL;
+          REQUIRE_CHAR(enc, ptr, end);
           t = BYTE_TYPE(enc, ptr);
           if (t == open)
             break;
@@ -624,8 +627,7 @@
           }
         }
         ptr += MINBPC(enc);
-        if (ptr == end)
-          return XML_TOK_PARTIAL;
+        REQUIRE_CHAR(enc, ptr, end);
         switch (BYTE_TYPE(enc, ptr)) {
         case BT_S:
         case BT_CR:
@@ -642,8 +644,7 @@
         /* ptr points to closing quote */
         for (;;) {
           ptr += MINBPC(enc);
-          if (ptr == end)
-            return XML_TOK_PARTIAL;
+          REQUIRE_CHAR(enc, ptr, end);
           switch (BYTE_TYPE(enc, ptr)) {
           CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
           case BT_S: case BT_CR: case BT_LF:
@@ -655,8 +656,7 @@
           case BT_SOL:
           sol:
             ptr += MINBPC(enc);
-            if (ptr == end)
-              return XML_TOK_PARTIAL;
+            REQUIRE_CHAR(enc, ptr, end);
             if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
               *nextTokPtr = ptr;
               return XML_TOK_INVALID;
@@ -688,13 +688,12 @@
 #ifdef XML_NS
   int hadColon;
 #endif
-  if (ptr == end)
-    return XML_TOK_PARTIAL;
+  REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   case BT_EXCL:
-    if ((ptr += MINBPC(enc)) == end)
-      return XML_TOK_PARTIAL;
+    ptr += MINBPC(enc);
+    REQUIRE_CHAR(enc, ptr, end);
     switch (BYTE_TYPE(enc, ptr)) {
     case BT_MINUS:
       return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -716,7 +715,7 @@
   hadColon = 0;
 #endif
   /* we have a start-tag */
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
 #ifdef XML_NS
@@ -727,8 +726,7 @@
       }
       hadColon = 1;
       ptr += MINBPC(enc);
-      if (ptr == end)
-        return XML_TOK_PARTIAL;
+      REQUIRE_CHAR(enc, ptr, end);
       switch (BYTE_TYPE(enc, ptr)) {
       CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
       default:
@@ -740,7 +738,7 @@
     case BT_S: case BT_CR: case BT_LF:
       {
         ptr += MINBPC(enc);
-        while (ptr != end) {
+        while (HAS_CHAR(enc, ptr, end)) {
           switch (BYTE_TYPE(enc, ptr)) {
           CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
           case BT_GT:
@@ -765,8 +763,7 @@
     case BT_SOL:
     sol:
       ptr += MINBPC(enc);
-      if (ptr == end)
-        return XML_TOK_PARTIAL;
+      REQUIRE_CHAR(enc, ptr, end);
       if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
@@ -785,7 +782,7 @@
 PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
                    const char **nextTokPtr)
 {
-  if (ptr == end)
+  if (ptr >= end)
     return XML_TOK_NONE;
   if (MINBPC(enc) > 1) {
     size_t n = end - ptr;
@@ -803,7 +800,7 @@
     return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
   case BT_CR:
     ptr += MINBPC(enc);
-    if (ptr == end)
+    if (! HAS_CHAR(enc, ptr, end))
       return XML_TOK_TRAILING_CR;
     if (BYTE_TYPE(enc, ptr) == BT_LF)
       ptr += MINBPC(enc);
@@ -814,12 +811,12 @@
     return XML_TOK_DATA_NEWLINE;
   case BT_RSQB:
     ptr += MINBPC(enc);
-    if (ptr == end)
+    if (! HAS_CHAR(enc, ptr, end))
       return XML_TOK_TRAILING_RSQB;
     if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
       break;
     ptr += MINBPC(enc);
-    if (ptr == end)
+    if (! HAS_CHAR(enc, ptr, end))
       return XML_TOK_TRAILING_RSQB;
     if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
       ptr -= MINBPC(enc);
@@ -832,7 +829,7 @@
     ptr += MINBPC(enc);
     break;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: \
@@ -845,12 +842,12 @@
     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
 #undef LEAD_CASE
     case BT_RSQB:
-      if (ptr + MINBPC(enc) != end) {
+      if (HAS_CHARS(enc, ptr, end, 2)) {
          if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
            ptr += MINBPC(enc);
            break;
          }
-         if (ptr + 2*MINBPC(enc) != end) {
+         if (HAS_CHARS(enc, ptr, end, 3)) {
            if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
              ptr += MINBPC(enc);
              break;
@@ -884,8 +881,7 @@
 PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
                     const char **nextTokPtr)
 {
-  if (ptr == end)
-    return XML_TOK_PARTIAL;
+  REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
@@ -895,7 +891,7 @@
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_SEMI:
@@ -913,15 +909,14 @@
 PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
                       const char **nextTokPtr)
 {
-  if (ptr == end)
-    return XML_TOK_PARTIAL;
+  REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   default:
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_CR: case BT_LF: case BT_S:
@@ -941,7 +936,7 @@
                 const char *ptr, const char *end,
                 const char **nextTokPtr)
 {
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     int t = BYTE_TYPE(enc, ptr);
     switch (t) {
     INVALID_CASES(ptr, nextTokPtr)
@@ -950,7 +945,7 @@
       ptr += MINBPC(enc);
       if (t != open)
         break;
-      if (ptr == end)
+      if (! HAS_CHAR(enc, ptr, end))
         return -XML_TOK_LITERAL;
       *nextTokPtr = ptr;
       switch (BYTE_TYPE(enc, ptr)) {
@@ -973,7 +968,7 @@
                   const char **nextTokPtr)
 {
   int tok;
-  if (ptr == end)
+  if (ptr >= end)
     return XML_TOK_NONE;
   if (MINBPC(enc) > 1) {
     size_t n = end - ptr;
@@ -992,8 +987,7 @@
   case BT_LT:
     {
       ptr += MINBPC(enc);
-      if (ptr == end)
-        return XML_TOK_PARTIAL;
+      REQUIRE_CHAR(enc, ptr, end);
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_EXCL:
         return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -1021,7 +1015,7 @@
   case BT_S: case BT_LF:
     for (;;) {
       ptr += MINBPC(enc);
-      if (ptr == end)
+      if (! HAS_CHAR(enc, ptr, end))
         break;
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_S: case BT_LF:
@@ -1048,11 +1042,10 @@
     return XML_TOK_OPEN_BRACKET;
   case BT_RSQB:
     ptr += MINBPC(enc);
-    if (ptr == end)
+    if (! HAS_CHAR(enc, ptr, end))
       return -XML_TOK_CLOSE_BRACKET;
     if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
-      if (ptr + MINBPC(enc) == end)
-        return XML_TOK_PARTIAL;
+      REQUIRE_CHARS(enc, ptr, end, 2);
       if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
         *nextTokPtr = ptr + 2*MINBPC(enc);
         return XML_TOK_COND_SECT_CLOSE;
@@ -1065,7 +1058,7 @@
     return XML_TOK_OPEN_PAREN;
   case BT_RPAR:
     ptr += MINBPC(enc);
-    if (ptr == end)
+    if (! HAS_CHAR(enc, ptr, end))
       return -XML_TOK_CLOSE_PAREN;
     switch (BYTE_TYPE(enc, ptr)) {
     case BT_AST:
@@ -1141,7 +1134,7 @@
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_GT: case BT_RPAR: case BT_COMMA:
@@ -1154,8 +1147,7 @@
       ptr += MINBPC(enc);
       switch (tok) {
       case XML_TOK_NAME:
-        if (ptr == end)
-          return XML_TOK_PARTIAL;
+        REQUIRE_CHAR(enc, ptr, end);
         tok = XML_TOK_PREFIXED_NAME;
         switch (BYTE_TYPE(enc, ptr)) {
         CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
@@ -1204,10 +1196,10 @@
                           const char *end, const char **nextTokPtr)
 {
   const char *start;
-  if (ptr == end)
+  if (ptr >= end)
     return XML_TOK_NONE;
   start = ptr;
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: ptr += n; break;
@@ -1232,7 +1224,7 @@
     case BT_CR:
       if (ptr == start) {
         ptr += MINBPC(enc);
-        if (ptr == end)
+        if (! HAS_CHAR(enc, ptr, end))
           return XML_TOK_TRAILING_CR;
         if (BYTE_TYPE(enc, ptr) == BT_LF)
           ptr += MINBPC(enc);
@@ -1262,10 +1254,10 @@
                        const char *end, const char **nextTokPtr)
 {
   const char *start;
-  if (ptr == end)
+  if (ptr >= end)
     return XML_TOK_NONE;
   start = ptr;
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: ptr += n; break;
@@ -1294,7 +1286,7 @@
     case BT_CR:
       if (ptr == start) {
         ptr += MINBPC(enc);
-        if (ptr == end)
+        if (! HAS_CHAR(enc, ptr, end))
           return XML_TOK_TRAILING_CR;
         if (BYTE_TYPE(enc, ptr) == BT_LF)
           ptr += MINBPC(enc);
@@ -1326,15 +1318,15 @@
       end = ptr + n;
     }
   }
-  while (ptr != end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     INVALID_CASES(ptr, nextTokPtr)
     case BT_LT:
-      if ((ptr += MINBPC(enc)) == end)
-        return XML_TOK_PARTIAL;
+      ptr += MINBPC(enc);
+      REQUIRE_CHAR(enc, ptr, end);
       if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
-        if ((ptr += MINBPC(enc)) == end)
-          return XML_TOK_PARTIAL;
+        ptr += MINBPC(enc);
+        REQUIRE_CHAR(enc, ptr, end);
         if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
           ++level;
           ptr += MINBPC(enc);
@@ -1342,11 +1334,11 @@
       }
       break;
     case BT_RSQB:
-      if ((ptr += MINBPC(enc)) == end)
-        return XML_TOK_PARTIAL;
+      ptr += MINBPC(enc);
+      REQUIRE_CHAR(enc, ptr, end);
       if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
-        if ((ptr += MINBPC(enc)) == end)
-          return XML_TOK_PARTIAL;
+        ptr += MINBPC(enc);
+        REQUIRE_CHAR(enc, ptr, end);
         if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
           ptr += MINBPC(enc);
           if (level == 0) {
@@ -1373,7 +1365,7 @@
 {
   ptr += MINBPC(enc);
   end -= MINBPC(enc);
-  for (; ptr != end; ptr += MINBPC(enc)) {
+  for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
     switch (BYTE_TYPE(enc, ptr)) {
     case BT_DIGIT:
     case BT_HEX:
@@ -1521,7 +1513,7 @@
 }
 
 static int PTRFASTCALL
-PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
 {
   int result = 0;
   /* skip &# */
@@ -1565,7 +1557,7 @@
 }
 
 static int PTRCALL
-PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
                              const char *end)
 {
   switch ((end - ptr)/MINBPC(enc)) {
@@ -1683,11 +1675,11 @@
 }
 
 static int PTRCALL
-PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
                          const char *end1, const char *ptr2)
 {
   for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
-    if (ptr1 == end1)
+    if (end1 - ptr1 < MINBPC(enc))
       return 0;
     if (!CHAR_MATCHES(enc, ptr1, *ptr2))
       return 0;
@@ -1744,7 +1736,7 @@
                        const char *end,
                        POSITION *pos)
 {
-  while (ptr < end) {
+  while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: \
@@ -1760,7 +1752,7 @@
     case BT_CR:
       pos->lineNumber++;
       ptr += MINBPC(enc);
-      if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+      if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF)
         ptr += MINBPC(enc);
       pos->columnNumber = (XML_Size)-1;
       break;
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index 453a737..09bef51 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -509,6 +509,7 @@
   FIND_PACKAGE(OpenSSL)
   IF(OPENSSL_FOUND)
     SET(HAVE_LIBCRYPTO 1)
+    INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
   ENDIF(OPENSSL_FOUND)
 ELSE()
   SET(OPENSSL_FOUND FALSE) # Override cached value